关于 webpack 相关的文章太多了,何不一块儿从零开始手写一个配置呢?css
真的3秒能打包一个three.js项目吗?真的,后面会提供源文件地址哦。html
要打包的项目是这个样子的。 前端
关于 three.js
的安装和使用部分都省略。node
首先是最基础的。咱们须要安装webpack
cross-env
目前最流行的运行跨平台设置和使用环境变量的脚本webpack
+ webpack-cli
+ webpack-dev-server
:三'贱'客,项目必备参考常规webpack配置结构须要3个最基础文件:git
webpack.base.js
webpack.dev.js
webpack.prod.js
固然,须要把 dev
或 prod
中的配置和 base
的配置合并起来,安装个webpack-merge
吧。github
而后配置一下最熟悉的脚本运行环节吧。经过--config
来对标配置文件,通cross-env
设置环境变量web
"dev": "cross-env NODE_ENV=dev webpack-dev-server --config script/webpack.dev.js",
"build": "cross-env NODE_ENV=prod webpack --config script/webpack.prod.js"
复制代码
好的,初期准备工做都OK开始配置环节。npm
首先是webpack的出入口。出口设置为 dist 环节简单直接上代码。json
{
entry: './src/index.js',
output: {
filename: '[name].[hash:8].js',
path: rootResolve('dist'),
publicPath: '/'
},
}
复制代码
顺便配置下别名。依然能够直接上代码
resolve: {
extensions: ['.js', '.json'],
alias: {
'@': rootResolve('src'),
'@assets': rootResolve('src/assets'),
}
}
复制代码
而后是关键环节:loader
和 plugins
关于 loader
:
less
less-loader
解析 less
由于 webpack 只能读懂jspostcss-loader
加上浏览器前缀css-loader
解析css代码中的 url
、@import
语法MiniCssExtractPlugin.loader
生成 .css
文件babel-loader
,关于 babel
文章太多了,暂略
HappyPack
进行优化加速thread-loader
呢? (由于名字很差听 - -!
怪我咯)url-loader
咯。而后 loader
配置就是这样的
{
test: /\.less$/,
exclude: /(node_modules|bower_components)/,
loaders: [{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: true,
hmr: process.env.NODE_ENV === 'dev', // 热更新
// publicPath: '../',
}
}, 'css-loader', 'postcss-loader', 'less-loader']
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
loader: 'happypack/loader',
options: {
id: 'babel',
}
},
{
test: /\.(png|jpe?g|gif)(\?.*)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 8192,
name: 'assets/img/[hash:8].[ext]'
}
}]
}
复制代码
关于插件部分,首先是配合上面 loader
的相关插件:HappyPack
和 MiniCssExtractPlugin
new MiniCssExtractPlugin({
filename: "css/[name].[hash:8].css", // css 路径
}),
new HappyPack({
id: 'babel',
loaders: [{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
cacheDirectory: true
}
}]
})
复制代码
固然,我想知道运行和打包的进度: ProgressPlugin
,顺便弄个 DefinePlugin
工程化必备插件。最后webpack生成后的代码注入不能少了 HtmlWebpackPlugin
而后 base
文件的插件结构是这样的
plugins: [
new webpack.ProgressPlugin(),
new webpack.DefinePlugin({
NODE_ENV: JSON.stringify(process.env.NODE_ENV), // 当前使用环境
VERSION: JSON.stringify('0.1.0'),
}),
new MiniCssExtractPlugin({
filename: "css/[name].[hash:8].css", // css 路径
// chunkFilename: "[id].css",
}),
new HappyPack({
id: 'babel',
loaders: [{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
cacheDirectory: true
}
}]
}),
new HtmlWebpackPlugin({ template: './src/index.html' })
]
复制代码
首先开发环境 api 代理必不可少。那么就是 devServer.proxy
了,顺便再定义下开发环境端口号。
devServer: {
contentBase: path.join(__dirname, "dist"),
compress: true,
port: 3333
}
复制代码
目前也没有太多事情,那么 merge 下再配个 HotModuleReplacementPlugin
吧
merge(base, {
mode: 'development',
plugins: [
],
devServer: {
contentBase: rootResolve("src"),
compress: true,
port: 3333
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
})
复制代码
打包环境主要作了这几件事情
首先是 dll
webpack.dll.config.js
manifest.dll.json
那么 webpack.dll.config.js
内容应该是这样的
{
// 你想要打包的模块的数组
entry: {
vendor: ['three']
},
output: {
filename: '[name].dll.js',
path: distResolve('dll'), // 打包后文件输出的位置
library: '[name]_library'
// 这里须要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
},
plugins: [
new webpack.DllPlugin({
name: '[name]_library',
path: distResolve('dll/manifest.dll.json'),
context: __dirname
})
]
}
复制代码
DllReferencePlugin
+ json文件
把 dll模块的详细要点告诉 webpack在 prod
文件中添加 plugins
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require(distResolve('./dll/manifest.dll.json'))
})
复制代码
"dll": "webpack --config script/webpack.dll.config.js",
复制代码
运行下 npm run dll
,在 dist/dll
目录下生成dll相关文件,那么 dll
配置也完成了。顺便作一些清理工做,用下 CleanWebpackPlugin
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [
'assets', 'js', 'css', 'index.html', '*.js',
'!manifest.dll.json', '!vendor.dll.js' // 不删除 dll 文件
],
})
复制代码
而后是代码优化,其实当 mode: 'production'
时已经作了不少代码优化相关的事情了。(我无论,我就是要优化 - -!
)
作一下 js的并行压缩吧
optimization: {
minimizer: [
new TerserWebpackPlugin({
parallel: true, // 启用并行压缩
cache: true, // 启用缓存
}),
new OptimizeCssAssetsPlugin({ // 压缩css
cssProcessorOptions: {
safe: true
}
})
],
runtimeChunk: true, // 自动拆分runtime文件
splitChunks: {
chunks: 'async',
minSize: 30000,
automaticNameDelimiter: '~',
automaticNameMaxLength: 30,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
},
}
复制代码
欧耶,再配置下js的打包后路径就行了
output: { // JS 路径
path: distResolve(),
filename: 'js/[id].[chunkhash].js',
chunkFilename: 'js/[name].[chunkhash].js'
},
复制代码
最后 merge
下 base
配置。在 dev
时作过了... 省略。
至此,Webpack配置已经大部分完成了,运行npm run build
打包代码,一、二、3。 3秒打包完成了。
为何只须要3秒呢?虽然上面的配置确实作了不少优化,可是大部分事情都被表象迷惑了,具体为什么下一章见。