React從入門到放棄之前奏(1):webpack4簡介
接觸webpack是好久之前的事情了,最近看了下webpack沒想到都到4了。
webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler).
會創建1個依賴關系圖(dependency graph),包含所有依賴的模塊,然後將模塊打包成1個或多個bundle.
webpack4 仍然支持高度可配,但完全可以不用配置文件了(基於mode)。
核心配置:
- 入口(entry):
- 輸出(output):
- loader:
- 插件(plugins):
基本特性
Entry
入口起點(entry point)指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始。
可以通過在 webpack 配置中配置 entry 屬性,來指定一個入口起點(或多個入口起點)。默認值為 ./src/index.js
webpack.config.js
module.exports = {
entry: {
main: './src/index.js'
},
};
Output
output 屬性告訴 webpack 在哪裏輸出它所創建的 bundles,以及如何命名這些文件,默認值為./dist/[name].js
webpack.config.js
const path = require('path');
module .exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
};
Loader
loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。
loaders 有2個核心參數:
- test 屬性,用於標識出需要轉換的某個或某些文件。
- use 屬性,表示進行轉換時,應該使用哪個 loader。
const path = require('path');
const config = {
output: {
filename: 'bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};
module.exports = config;
Plugins
插件的範圍包括,從打包優化和壓縮,一直到重新定義環境中的變量。插件接口功能極其強大,可以用來處理各種各樣的任務。
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通過 npm 安裝
const webpack = require('webpack'); // 用於訪問內置插件
const config = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
Mode
通過選擇 development 或 production 之中的一個,來設置 mode 參數
webpack.config.js
module.exports = {
mode: 'production'
};
mode.js
// webpack.development.config.js
module.exports = {
+ mode: 'development'
- plugins: [
- new webpack.NamedModulesPlugin(),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
- ]
}
// webpack.production.config.js
module.exports = {
+ mode: 'production',
- plugins: [
- new UglifyJsPlugin(/* ... */),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
- new webpack.optimize.ModuleConcatenationPlugin(),
- new webpack.NoEmitOnErrorsPlugin()
- ]
}
常用插件
HtmlWebpackPlugin:
Options
const HtmlWebpackPlugin = require('html-webpack-plugin');
new HtmlWebpackPlugin({ template: 'src/index.html', minify: true, hash: true })
CleanWebpackPlugin:
const CleanWebpackPlugin = require('clean-webpack-plugin');
new CleanWebpackPlugin(['dist'])
MiniCssExtractPlugin(ExtractTextPlugin):
new MiniCssExtractPlugin({ filename: "[name].css",chunkFilename: "[id].css" })
module: {
rules: [{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]}
]
}
SplitChunksPlugin:
module.exports = {
mode: 'development',
entry: {
main: './src/index.js',
vendors: 'lodash'
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "initial"
}
}
}
}
}
配置示例
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
module.exports = {
mode: 'development',
entry: {
main: './src/index.js',
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
module: {
rules: [{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]
}, {
test: /\.(js|jsx)$/,
loader: 'babel-loader',
options: {
presets: ['react']
},
exclude: /node_modules/
}]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({ template: 'src/index.html', minify: true, hash: true }),
new MiniCssExtractPlugin({ filename: "[name].css", chunkFilename: "[id].css" })
],
externals: {
lodash: '_',
react: 'React',
'react-dom': 'ReactDOM'
},
optimization: {
splitChunks: {
cacheGroups: {
common: {
test: /[\\/]node_modules[\\/]/,
name: "common",
chunks: "initial"
}
}
}
}
};
React從入門到放棄之前奏(1):webpack4簡介