webpack 核心概念:
webpack流程:
webpack啓動後會從 Entry 裏配置的 Module 開始遞歸解析 Entry 依賴的全部Module.每找到一個Module,就會根據配置的Loader去找出對應的轉換規則,對Module進行轉換後,再解析出當前的Module依賴的Module.這些模塊會以Entry爲單位進行分組,一個Entry和其全部依賴的Module被分到一個組也就是一個Chunk。最好Webpack會把全部Chunk轉換成文件輸出。在整個流程中Webpack會在恰當的時機執行Plugin裏定義的邏輯。javascript
下面咱們開始從零開始配置一個支持打包圖片,CSS,LESS,SASS,支持ES6/ES7和JSX語法,並對代碼進行壓縮的webpack配置.css
1. 最簡webpack配置
首先初始化npm和安裝webpack的依賴:html
npm init -y npm install --save-dev webpack webpack-cli
配置 webpack.config.js 文件以下:前端
const path = require('path'); module.exports = { entry: path.resolve(__dirname, 'src/index.js'), output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath: '/' } }
說明: publicPath 上線時配置的是cdn的地址。java
使用命令進行打包:node
webpack --mode production
也能夠將其配置到 package.json 中的 scripts 字段.react
入口文件爲 src/index.js, 打包輸出到 dist/bundle.js.webpack
2. 使用模板 html
html-webpack-plugin 能夠指定template模板文件,將會在output目錄下,生成html文件,並引入打包後的js.git
安裝依賴:github
npm install --save-dev html-webpack-plugin
在 webpack.config.js 增長 plugins 配置:
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //...other code plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'src/index.html') }) ] }
HtmlWebpackPlugin 還有一些其它的參數,如title(html的title),minify(是否要壓縮),filename(dist中生成的html的文件名)等
3. 配置 webpack-dev-server
webpack-dev-server提供了一個簡單的Web服務器和實時熱更新的能力
安裝依賴:
npm install --save-dev webpack-dev-server
在 webpack.config.js 增長 devServer 配置:
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //...other code devServer: { contentBase: './dist', port: '8080', host: 'localhost' } }
在 package.json 的 scripts 字段中增長:
webpack-dev-server --mode development
以後,咱們就能夠經過 npm run dev , 來啓動服務。
更多 webpack-dev-server 的知識,請訪問: https://webpack.js.org/config...
4. 支持加載css文件
經過使用不一樣的 style-loader 和 css-loader, 能夠將 css 文件轉換成JS文件類型。
安裝依賴:
npm install --save-dev style-loader css-loader
在 webpack.config.js 中增長 loader 的配置。
module.exports = { //other code module: { rules: [ { test: /\.css/, use: ['style-loader', 'css-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') } ] } }
loader 能夠配置如下參數:
若是須要給loader傳參,那麼可使用use+loader的方式,如:
module.exports = { //other code module: { rules: [ { use: [{ loader: 'style-loader', options: { insertAt: 'top' } }, 'css-loader' ], //.... } ] } }
5. 支持加載圖片
若是但願圖片存放在單獨的目錄下,那麼須要指定outputPath
安裝依賴:
npm install --save-dev url-loader file-loader
在 webpack.config.js 中增長 loader 的配置(增長在 module.rules 的數組中)。
module.exports = { //other code module: { rules: [ { test: /\.(gif|jpg|png|bmp|eot|woff|woff2|ttf|svg)/, use: [ { loader: 'url-loader', options: { limit: 8192, outputPath: 'images' } } ] } ] } }
6.支持編譯less和sass
有些前端同事可能習慣於使用less或者是sass編寫css,那麼也須要在 webpack 中進行配置。
安裝對應的依賴:
npm install --save-dev less less-loader npm install --save-dev node-sass sass-loader
在 webpack.config.js 中增長 loader 的配置(module.rules 數組中)。
module.exports = { //other code module: { rules: [ { test: /\.less/, use: ['style-loader', 'css-loader', 'less-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.scss/, use: ['style-loader', 'css-loader', 'sass-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') } ] } }
7.支持轉義 ES6/ES7/JSX
ES6/ES7/JSX 轉義須要 Babel 的依賴,支持裝飾器。
npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread
在 webpack.config.js 中增長 loader 的配置(module.rules 數組中)。
module.exports = { //other code module: { rules: [ { test: /\.jsx?$/, use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/react'], plugins: [ [require("@babel/plugin-proposal-decorators"), { "legacy": true }] ] } } ], include: path.resolve(__dirname, 'src'), exclude: /node_modules/ }, ] } }
8.壓縮JS文件
安裝依賴:
npm install --save-dev uglifyjs-webpack-plugin npm install --save-dev optimize-css-assets-webpack-plugin
在 webpack.config.js 中增長 optimization 的配置
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin'); module.exports = { //other code optimization: { minimizer: [ new UglifyWebpackPlugin({ parallel: 4 }) ] } }
9.分離CSS(若是CSS文件較大的話)
由於CSS的下載和JS能夠並行,當一個HTML文件很大的時候,能夠把CSS單獨提取出來加載
npm install --save-dev mini-css-extract-plugin
在 webpack.config.js 中增長 plugins 的配置,而且將 'style-loader' 修改成 { loader: MiniCssExtractPlugin.loader}。
CSS打包在單獨目錄,那麼配置filename。
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { //other code module: { rules: [ { test: /\.css/, use: [{ loader: MiniCssExtractPlugin.loader}, 'css-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.less/, use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'less-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.scss/, use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'sass-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, ] }, plugins: [ new MiniCssExtractPlugin({ filename: 'css/[name].css' }) ] }
10.壓縮CSS文件
安裝依賴:
npm install --save-dev optimize-css-assets-webpack-plugin
在 webpack.config.js 中的 optimization 中增長配置
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { //other code optimization: { minimizer: [ new OptimizeCssAssetsWebpackPlugin() ] } }
11.打包前先清空輸出目錄
npm install --save-dev clean-webpack-plugin
在 webpack.config.js 中增長 plugins 的配置
const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { //other code plugins: [ new CleanWebpackPlugin() ] }
至此,webpack配置已經基本能知足需求。
完整webpack.config.js和package.json文件
webpack.config.js文件:
const path = require('path'); const htmlWebpackPlugin = require('html-webpack-plugin'); const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { entry: path.resolve(__dirname, 'src/index.js'), output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath: '/' }, devServer: { contentBase: './dist', port: '8080', host: 'localhost' }, module: { rules: [ { test: /\.jsx?$/, use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/react'], plugins: [ [require("@babel/plugin-proposal-decorators"), { "legacy": true }] ] } } ], include: path.resolve(__dirname, 'src'), exclude: /node_modules/ }, { test: /\.css/, use: [{ loader: MiniCssExtractPlugin.loader}, 'css-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.less/, use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'less-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.scss/, use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'sass-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.(gif|jpg|png|bmp|eot|woff|woff2|ttf|svg)/, use: [ { loader: 'url-loader', options: { limit: 1024, outputPath: 'images' } } ] } ] }, optimization: { minimizer: [ new UglifyWebpackPlugin({ parallel: 4 }), new OptimizeCssAssetsWebpackPlugin() ] }, plugins: [ new htmlWebpackPlugin({ template: path.resolve(__dirname, 'src/index.html'), }), new MiniCssExtractPlugin({ filename: 'css/[name].css' }), new CleanWebpackPlugin() ] }
package.json文件:
{ "name": "webpk", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode production", "dev": "webpack-dev-server --mode development" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.4.0", "@babel/plugin-proposal-decorators": "^7.4.0", "@babel/plugin-proposal-object-rest-spread": "^7.4.0", "@babel/preset-env": "^7.4.1", "@babel/preset-react": "^7.0.0", "babel-loader": "^8.0.5", "clean-webpack-plugin": "^2.0.1", "css-loader": "^2.1.1", "file-loader": "^3.0.1", "html-webpack-plugin": "^3.2.0", "less": "^3.9.0", "less-loader": "^4.1.0", "mini-css-extract-plugin": "^0.5.0", "node-sass": "^4.11.0", "optimize-css-assets-webpack-plugin": "^5.0.1", "sass-loader": "^7.1.0", "style-loader": "^0.23.1", "uglifyjs-webpack-plugin": "^2.1.2", "url-loader": "^1.1.2", "webpack": "^4.29.6", "webpack-cli": "^3.3.0", "webpack-dev-server": "^3.2.1" }, "dependencies": { "react": "^16.8.4", "react-dom": "^16.8.4", "react-redux": "^6.0.1", "redux": "^4.0.1" } }
更多loader和plugin的參數能夠參考:
https://www.webpackjs.com/loa...
https://www.webpackjs.com/plu...
謝謝您花費寶貴的時間閱讀本文,若是本文給了您一點幫助或者是啓發,那麼不要吝嗇你的贊和Star哈,您的確定是我前進的最大動力。https://github.com/YvetteLau/...
若是你有其它的webpack配置需求,歡迎留言~
推薦關注本人公衆號: