webpack快速入門教程
測試文檔見github 記得star 哦
1郑气、了解Webpack相關
- 什么是webpack
- Webpack是一個模塊打包器(bundler)。
- 在Webpack看來, 前端的所有資源文件(js/json/css/img/less/...)都會作為模塊處理
- 它將根據模塊的依賴關系進行靜態(tài)分析揽乱,生成對應的靜態(tài)資源
- 五個核心概念
- Entry:入口起點(entry point)指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始粟矿。
- Output:output 屬性告訴 webpack 在哪里輸出它所創(chuàng)建的 bundles凰棉,以及如何命名這些文件,默認值為 ./dist陌粹。
- Loader:loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只能解析 JavaScript)撒犀。
- Plugins:插件則可以用于執(zhí)行范圍更廣的任務。插件的范圍包括掏秩,從打包優(yōu)化和壓縮或舞,一直到重新定義環(huán)境中的變量等。
- Mode:模式蒙幻,有生產模式production和開發(fā)模式development
- 理解Loader
- Webpack 本身只能加載JS/JSON模塊映凳,如果要加載其他類型的文件(模塊),就需要使用對應的loader 進行轉換/加載
- Loader 本身也是運行在 node.js 環(huán)境中的 JavaScript 模塊
- 它本身是一個函數邮破,接受源文件作為參數诈豌,返回轉換的結果
- loader 一般以 xxx-loader 的方式命名仆救,xxx 代表了這個 loader 要做的轉換功能,比如 json-loader矫渔。
- 理解Plugins
- 插件可以完成一些loader不能完成的功能彤蔽。
- 插件的使用一般是在 webpack 的配置信息 plugins 選項中指定。
- 配置文件(默認)
- webpack.config.js : 是一個node模塊庙洼,返回一個 json 格式的配置信息對象
2顿痪、開啟項目
-
初始化項目:
-
生成package.json文件
{ "name": "webpack_test", "version": "1.0.0" }
-
-
安裝webpack
- npm install webpack webpack-cli -g //全局安裝,作為指令使用
- npm install webpack webpack-cli -D //本地安裝,作為本地依賴使用
3、編譯打包應用
- 創(chuàng)建js文件
- src/js/app.js
- src/js/module1.js
- src/js/module2.js
- src/js/module3.js
- 創(chuàng)建json文件
- src/json/data.json
- 創(chuàng)建主頁面:
- src/index.html
- 運行指令
- 開發(fā)配置指令:webpack src/js/app.js -o dist/js/app.js --mode=development
- 功能: webpack能夠編譯打包js和json文件送膳,并且能將es6的模塊化語法轉換成瀏覽器能識別的語法
- 生產配置指令:webpack src/js/app.js -o dist/js/app.js --mode=production
- 功能: 在開發(fā)配置功能上加上一個壓縮代碼
- 開發(fā)配置指令:webpack src/js/app.js -o dist/js/app.js --mode=development
- 結論:
- webpack能夠編譯打包js和json文件
- 能將es6的模塊化語法轉換成瀏覽器能識別的語法
- 能壓縮代碼
- 缺點:
- 不能編譯打包css员魏、img等文件
- 不能將js的es6基本語法轉化為es5以下語法
- 改善:使用webpack配置文件解決,自定義功能
4叠聋、使用webpack配置文件
目的:在項目根目錄定義配置文件撕阎,通過自定義配置文件,還原以上功能
文件名稱:webpack.config.js
-
文件內容:
const { resolve } = require('path'); //node內置核心模塊碌补,用來設置路徑虏束。 module.exports = { entry: './src/js/app.js', // 入口文件配置(簡寫) /*完整寫法: entry:{ main:'./src/js/app.js' } */ output: { // 輸出配置 filename: './js/built.js', // 輸出文件名 path: resolve(__dirname, 'build') //輸出文件路徑配置 }, mode: 'development' //開發(fā)環(huán)境(二選一) mode: 'production' //生產環(huán)境(二選一) };
運行指令: webpack
5、打包less資源
概述:less文件webpack不能解析厦章,需要借助loader編譯解析
-
創(chuàng)建less文件
- src/less/test1.less
- src/less/test2.less
-
入口app.js文件
- 引入less資源
-
安裝loader
- npm install css-loader style-loader less-loader less --save-dev
-
配置loader
{ test: /\.less$/, // 檢查文件是否以.less結尾(檢查是否是less文件) use: [ // 數組中l(wèi)oader執(zhí)行是從下到上镇匀,從右到左順序執(zhí)行 'style-loader', // 創(chuàng)建style標簽,添加上js中的css代碼 'css-loader', // 將css以commonjs方式整合到js文件中 'less-loader' // 將less文件解析成css文件 ] },
運行指令:webpack
6袜啃、js語法檢查
概述:對js基本語法錯誤/隱患汗侵,進行提前檢查
-
安裝loader
- npm install eslint-loader eslint --save-dev
備注1:在:eslint.org網站 -> userGuide -> Configuring ESLint 查看如何配置
備注2:在:eslint.org網站 -> userGuide -> Rules 查看所有規(guī)則
-
配置loader
module: { rules: [ { test: /\.js$/, //只檢測js文件 exclude: /node_modules/, //排除node_modules文件夾 enforce: "pre", //提前加載使用 use: { //使用eslint-loader解析 loader: "eslint-loader" } } ] }
-
修改package.json(需要刪除注釋才能生效)
"eslintConfig": { "parserOptions": { "ecmaVersion": 6, // 支持es6 "sourceType": "module" // 使用es6模塊化 }, "env": { // 設置環(huán)境 "browser": true, // 支持瀏覽器環(huán)境: 能夠使用window上的全局變量 "node": true // 支持服務器環(huán)境: 能夠使用node上global的全局變量 }, "globals": { // 聲明使用的全局變量, 這樣即使沒有定義也不會報錯了 "$": "readonly" // $ 只讀變量 }, "rules": { // eslint檢查的規(guī)則 0 忽略 1 警告 2 錯誤 "no-console": 0, // 不檢查console "eqeqeq": 2, // 用==而不用===就報錯 "no-alert": 2 // 不能使用alert }, "extends": "eslint:recommended" // 使用eslint推薦的默認規(guī)則 https://cn.eslint.org/docs/rules/ },
運行指令:webpack
7、js語法轉換
概述:將瀏覽器不能識別的新語法轉換成原來識別的舊語法群发,做瀏覽器兼容性處理
-
安裝loader
- npm install babel-loader @babel/core @babel/preset-env --save-dev
-
配置loader
module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ['@babel/preset-env'] } } } ] }
運行指令:webpack
8晰韵、 js兼容性處理
第一種方法:使用經典的polyfill
-
安裝包
- npm install @babel/polyfill
-
使用
- app.js import '@babel/polyfill'; // 包含ES6的高級語法的轉換
優(yōu)點:解決babel只能轉換部分低級語法的問題(如:let/const/解構賦值...),引入polyfill可以轉換高級語法(如:Promise...)
缺點:將所有高級語法都進行了轉換熟妓,但實際上可能只使用一部分(無論開發(fā)使用了幾個新語法,全部轉換成低級語法,不推薦使用)
解決:需要按需加載(使用了什么高級語法雪猪,就轉換什么,而其他的不轉換)
第二種方法:借助按需引入core-js按需引入
-
安裝包
- npm install core-js
-
配置loader
{ test: /\.js$/, exclude: /(node_modules)/, use: { loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env', { useBuiltIns: 'usage', // 按需引入需要使用polyfill corejs: { version: 3 }, // 解決warn targets: { // 指定兼容性處理哪些瀏覽器 "chrome": "58", "ie": "9", } } ] ], cacheDirectory: true, // 開啟babel緩存 } } },
9起愈、打包樣式文件中的圖片資源
概述:圖片文件webpack不能解析只恨,需要借助loader編譯解析
-
添加2張圖片:
- 小圖, 小于8kb: src/images/vue.png
- 大圖, 大于8kb: src/images/react.jpg
在less文件中通過背景圖的方式引入圖片
-
安裝loader
- npm install file-loader url-loader --save-dev
- 補充:url-loader是對象file-loader的上層封裝,使用時需配合file-loader使用抬虽。
-
配置loader
{ test: /\.(png|jpg|gif)$/, use: { loader: 'url-loader', options: { limit: 8192, // 8kb --> 8kb以下的圖片會base64處理 outputPath: 'images', // 決定文件本地輸出路徑 publicPath: '../build/images', // 決定圖片的url路徑 name: '[hash:8].[ext]' // 修改文件名稱 [hash:8] hash值取8位 [ext] 文件擴展名 } } },
運行指令:webpack
10官觅、打包html文件
概述:html文件webpack不能解析,需要借助插件編譯解析
-
添加html文件
- src/index.html
- 注意不要在html中引入任何css和js文件
-
安裝插件Plugins
- npm install html-webpack-plugin --save-dev
-
在webpack.config.js中引入插件(插件都需要手動引入阐污,而loader會自動加載)
- const HtmlWebpackPlugin = require('html-webpack-plugin')
-
配置插件Plugins
plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', // 以當前文件為模板創(chuàng)建新的HtML(1. 結構和原來一樣 2. 會自動引入打包的資源) }), ]
運行指令:webpack
11缰猴、打包html中圖片資源
概述:html中的圖片url-loader沒法處理,它只能處理js中引入的圖片 / 樣式中圖片疤剑,不能處理html中img標簽滑绒,需要引入其他html-loader處理。
-
添加圖片
- 在src/index.html添加兩個img標簽
-
安裝loader
- npm install html-loader --save-dev
-
配置loader
{ test: /\.(html)$/, use: { loader: 'html-loader' } }
運行指令:webpack
12隘膘、打包其他資源
概述:其他資源webpack不能解析疑故,需要借助loader編譯解析
-
添加字體文件
- src/media/iconfont.eot
- src/media/iconfont.svg
- src/media/iconfont.ttf
- src/media/iconfont.woff
- src/media/iconfont.woff2
-
修改樣式
@font-face { font-family: 'iconfont'; src: url('../media/iconfont.eot'); src: url('../media/iconfont.eot?#iefix') format('embedded-opentype'), url('../media/iconfont.woff2') format('woff2'), url('../media/iconfont.woff') format('woff'), url('../media/iconfont.ttf') format('truetype'), url('../media/iconfont.svg#iconfont') format('svg'); } .iconfont { font-family: "iconfont" !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
修改html,添加字體
-
配置loader
{ test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/, // 處理其他資源 loader: 'file-loader', options: { outputPath: 'media', name: '[hash:8].[ext]' } }
運行指令:webpack
13弯菊、自動編譯打包運行
-
安裝loader
- npm install webpack-dev-server --save-dev
詳細配置見官網:指南 -> 開發(fā)環(huán)境 -> 使用webpack-dev-server
-
修改webpack配置對象(注意不是loader中)
devServer: { open: true, // 自動打開瀏覽器 compress: true, // 啟動gzip壓縮 port: 3000, // 端口號 }
-
修改url-loader部分配置
- 因為構建工具以build為根目錄纵势,不用再找build了
-
publicPath: '../build/images/'
-->publicPath: 'images/'
-
修改package.json中scripts指令
- "start": "webpack-dev-server",
-
運行指令:npm run start
- 注意
webpack-dev-server
指令才能啟動devServer配置,然后配置到package.json中才行
- 注意
14管钳、熱模替換功能
概述:熱模塊替換(HMR)是webpack提供的最有用的功能之一钦铁。它允許在運行時更新所有類型的模塊,而無需完全刷新(只更新變化的模塊才漆,不變的模塊不更新)牛曹。
詳細配置見官網:指南 -> 模塊熱替換
-
修改devServer配置
devServer: { contentBase: resolve(__dirname, 'build'), // 運行項目的目錄 open: true, // 自動打開瀏覽器 compress: true, // 啟動gzip壓縮 port: 3000, // 端口號 hot: true // 開啟熱模替換功能 HMR }
-
問題:html文件無法自動更新了,需要增加一個入口
entry: ['./src/js/app.js','./src/index.html']
15醇滥、devtool
- 概述: 一種將壓縮/編譯文件中的代碼映射回源文件中的原始位置的技術黎比,讓我們調試代碼不在困難
- 詳細配置見官網:配置 -> devtool
- 介紹
- cheap 只保留行, 編譯速度快
- eval webpack生成的代碼(每個模塊彼此分開,并使用模塊名稱進行注釋), 編譯速度快
- inline 以base64方式將source-map嵌入到代碼中鸳玩,缺點造成編譯后代碼體積很大
- 推薦使用:
- 開發(fā)環(huán)境: cheap-module-eval-source-map
- 生產環(huán)境: cheap-module-source-map
以上就是webpack開發(fā)環(huán)境的配置阅虫,可以在內存中自動打包所有類型文件并有自動編譯運行、熱更新等功能不跟。
16颓帝、準備生產環(huán)境
-
創(chuàng)建文件夾config,將webpack.config.js復制兩份
- ./config/webpack.dev.js
- ./config/webpack.prod.js
-
修改webpack.prod.js配置窝革,刪除webpack-dev-server配置
// / 代表根路徑(等價于這個:http://localhost:5000/)购城,以后項目上線所有路徑都以當前網址為根路徑出發(fā) module.exports = { output: { path: resolve(__dirname, '../build'), // 文件輸出目錄 filename: './js/built.js', // 文件輸出名稱 publicPath: '/' // 所有輸出資源在引入時的公共路徑,若loader中也指定了publicPath聊闯,會以loader的為準工猜。 }, module: { rules: [ { test: /\.(png|jpg|gif)$/, use: { loader: 'url-loader', options: { limit: 8192, outputPath: 'images', publicPath: '/images', // 重寫publicPath,需要在路徑前面加上 / name: '[hash:8].[ext]' } } }, ] }, mode: 'production', //修改為生產環(huán)境 devtool: 'cheap-module-source-map' // 修改為生產環(huán)境的錯誤提示 // 刪除devServer }
-
修改package.json的指令
- "start": "webpack-dev-server --config ./config/webpack.dev.js"
- "dev": "webpack-dev-server --config ./config/webpack.dev.js"
- "build": "webpack --config ./config/webpack.prod.js"
-
開發(fā)環(huán)境指令
- npm start
- npm run dev
-
生產環(huán)境指令
- npm run build
- 注意: 生產環(huán)境代碼需要部署到服務器上才能運行 (serve這個庫能幫助我們快速搭建一個靜態(tài)資源服務器)
- npm i serve -g
- serve -s build -p 5000
17菱蔬、清除打包文件目錄
- 概述:每次打包生成了文件篷帅,都需要手動刪除,引入插件幫助我們自動刪除上一次的文件
- 安裝插件
- npm install clean-webpack-plugin --save-dev
- 引入插件
- const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 注意要解構賦值K┟凇N荷怼!
- 配置插件
- new CleanWebpackPlugin() // 自動清除output.path目錄下的文件
- 運行指令:npm run build
18蚪腐、提取css成單獨文件
-
安裝插件
- npm install mini-css-extract-plugin --save-dev
-
引入插件
- const MiniCssExtractPlugin = require("mini-css-extract-plugin");
-
配置loader
{ test: /\.less$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'less-loader', ] }
-
配置插件
new MiniCssExtractPlugin({ filename: "css/[name].css", })
-
運行指令
- npm run build
- serve -s build
19箭昵、添加css兼容
-
安裝loader
- npm install postcss-loader postcss-flexbugs-fixes postcss-preset-env postcss-normalize autoprefixer --save-dev
-
配置loader
{ test: /\.less$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', { loader: 'postcss-loader', options: { ident: 'postcss', plugins: () => [ require('postcss-flexbugs-fixes'), require('postcss-preset-env')({ autoprefixer: { flexbox: 'no-2009', }, stage: 3, }), require('postcss-normalize')(), ], sourceMap: true, }, }, 'less-loader', ] }
-
添加配置文件: .browserslistrc
last 1 version > 1% IE 10 # sorry
-
運行指令:
- npm run build
- serve -s build
20、壓縮css
-
安裝插件
- npm install optimize-css-assets-webpack-plugin --save-dev
-
引入插件
- const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
-
配置插件
new OptimizeCssAssetsPlugin({ cssProcessorPluginOptions: { preset: ['default', { discardComments: { removeAll: true } }], }, cssProcessorOptions: { // 解決沒有source map問題 map: { inline: false, annotation: true, } } })
-
運行指令:
- npm run build
- serve -s build
21回季、壓縮html
-
修改插件配置
new HtmlWebpackPlugin({ template: './src/index.html', minify: { removeComments: true, collapseWhitespace: true, removeRedundantAttributes: true, useShortDoctype: true, removeEmptyAttributes: true, removeStyleLinkTypeAttributes: true, keepClosingSlash: true, minifyJS: true, minifyCSS: true, minifyURLs: true, } })
-
運行指令:
- npm run build
- serve -s dist
以上就是webpack生產環(huán)境的配置家制,可以生成打包后的文件正林。