本系列代码放在 github 上:
webpack4系列实践代码
如果本系列实践教程对你有帮助,欢迎给个
github star
哦!
1.开发环境和生产环境的 webpack 配置
开发环境和生产环境的构建目标是有很大的不同的。
在开发环境中,为了便于代码调试以及实现浏览器实时更新,我们需要开启 source map
和 localhost server
。
而在生成环境中,为了实现缓存优化以及改善加载时间,我们的目标转向于打包成更小的 bundle
或 chunk
,分离第三方包以及开启更轻量级的 source map
以及更优化的资源。
因此开发环境和生产环境需要单独配置 webpack。
2.定个需求
假设项目打包需求如下:
公共部分:
在开发环境下:
在生产环境下:
3.webpack配置文件
根据以上情况,我们需要定义三个webpack配置文件,分别是:
4.目录机构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| --demo19 --build -config.js -webpack.base.conf.js -webpack.dev.conf.js -webpack.prod.conf.js --src --app -app.ts --assets --fonts -icomoon.css -icomoon.eot -icomoon.svg -icomoon.ttf -icomoon.woff --images -1.png -2.png -3.png -me.jpg --styles -app.scss -index.html -postcss.config.js -tsconfig.json
|
代码放在github上
5.安装相关依赖
1 2 3 4 5 6 7 8 9 10
| npm install -D css-loader style-loader node-sass sass-loader npm install -D postcss postcss-loader autoprefixer npm install -D file-loader url-loader npm install -D ts-loader typescript npm install -D html-webpack-plugin clean-webpack-plugin npm install -D webpack-dev-server npm install -D mini-css-extract-plugin npm install -D optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin npm install -D webpack-merge npm install -D webpack webpack-cli
|
6.webpack配置文件如下
webpack.base.conf.js(开发和生产模式的公共配置)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| 'use strict' const path = require("path"); const isDev = /^dev/.test(process.env.npm_lifecycle_event); const config = require('./config'); const CleanWebpackPlugin = require("clean-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = { mode: isDev ? "development" : "production", entry: { app: "./src/app/app.ts" }, output: { publicPath: isDev ? config.dev.publicPath : config.prod.publicPath, path: path.resolve(__dirname, "..", "dist"), filename: isDev ? config.dev.filename : config.prod.filename, chunkFilename: isDev ? config.dev.chunkFilename : config.prod.chunkFilename }, resolve: { extensions: ['.ts', '.js'] }, module: { rules: [ { test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' }, { test: /\.(jpg|png|gif|bmp|jpeg)$/, use: [ { loader: 'url-loader', options: { limit: 20000, name: '[name].[hash].[ext]', publicPath: "imgs/", outputPath: "imgs/" } } ] }, { test: /\.ts?$/, use: 'ts-loader', exclude: /node_modules/ } ] }, plugins: [ new HtmlWebpackPlugin({ filename: "index.html", template: path.resolve(__dirname, "../src", "index.html"), minify: { collapseWhitespace: true } }), new CleanWebpackPlugin() ] };
|
webpack.dev.conf.js (开发模式所需配置)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 'use strict' const path = require('path'); const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf')
const devWebpackConfig = merge(baseWebpackConfig, { devtool: "source-map", devServer: { contentBase: path.join(__dirname, "../dist/"), port: 8000, hot: false, overlay: true, historyApiFallback: { rewrites: [{ from: /.*/, to: "/index.html" }] } }, module: { rules: [ { test: /\.(sa|sc|c)ss$/, use: [ "style-loader", "css-loader", { loader: 'postcss-loader' }, "sass-loader" ] } ] }, plugins: [] }); module.exports = devWebpackConfig;
|
webpack.prod.conf.js (生产模式所需配置)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| 'use strict' const merge = require('webpack-merge'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const baseWebpackConfig = require('./webpack.base.conf')
const prodWebpackConfig = merge(baseWebpackConfig, { module: { rules: [ { test: /\.(sa|sc|c)ss$/, use: [ MiniCssExtractPlugin.loader, "css-loader", { loader: 'postcss-loader', }, "sass-loader" ] } ] }, optimization: { runtimeChunk: "single", minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }), new OptimizeCSSAssetsPlugin({}) ], splitChunks: { cacheGroups: { async: { chunks: "async", maxInitialRequests: 3, automaticNameDelimiter: '~', priority: 9 }, vendors: { chunks: "all", test: /[\\/]node_modules[\\/]/, name: "vendors", priority: 10 } } } }, plugins: [ new MiniCssExtractPlugin({ filename: "[id].[name].[chunkhash:8].css", chunkFilename: "[id].[name].[chunkhash:8].css" }) ] });
module.exports = prodWebpackConfig;
|
5.配置 npm scripts 命令
在 package.json 中添加如下 npm scripts
1 2 3 4
| "scripts": { "dev": "webpack-dev-server --open --inline --progress --config build/webpack.dev.conf.js", "prod": "webpack --config build/webpack.prod.conf.js" },
|
6.执行命令
执行如下命令,开启开发调试模式,自动打开浏览器,当修改代码时,浏览器自动刷新,便于开发和调试。
执行如下命令,webpack将以production模式进行打包,实现代码压缩,分离第三方模块以及css为单独的chunk,这样有利于对单独的包进行缓存优化。
7.源码地址
demo 代码地址: https://github.com/SimpleCodeCX/simple-webpack-demos/tree/master/demo19-dev-prod
仓库代码地址(及目录): https://github.com/SimpleCodeCX/simple-webpack-demos