<div align="center">
<a href="https://github.com/webpack/webpack">
<img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
<p>
本文主要介绍,最新版本webpack 5在开发和生产环境下的常见配置、及常见错误。
</p>
</div>
<h1 align="center">Dependencies</h1>
Name | Status | Install Size | Description |
---|---|---|---|
<a href="https://github.com/webpack/webpack"><img width="48" height="48" src="https://cdn.worldvectorlogo.com/logos/webpack-icon.svg"></a> webpack |
模块打包器 | ||
<a href="https://github.com/webpack/webpack"><img width="48" height="48" src="https://cdn.worldvectorlogo.com/logos/webpack-icon.svg"></a> webpack-cli |
webpack官方命令行工具 | ||
<a href="https://github.com/webpack/webpack"><img width="48" height="48" src="https://cdn.worldvectorlogo.com/logos/webpack-icon.svg"></a> webpack-dev-server |
Serves a webpack app. Updates the browser on changes. | ||
<a href="https://github.com/webpack/webpack"><img width="48" height="48" src="https://cdn.worldvectorlogo.com/logos/webpack-icon.svg"></a> webpack-merge |
webpack配置文件merge | ||
<a href="https://github.com/webpack-contrib/style-loader"><style> </a> |
Add exports of a module as style to DOM | ||
<a href="https://github.com/webpack-contrib/css-loader"><img width="48" height="48" src="https://worldvectorlogo.com/logos/css-3.svg"></a> css-loader |
Loads CSS file with resolved imports and returns CSS code |
<h1 align="center">Usage</h1>
Description | 解决办法 |
---|---|
根据不同环境进行打包,共同项配置抽取出来 | 创建3个文件common.js(通用配置),dev.js(开发环境),prod.js(生产环境),引入webpack-merge包,参考 环境配置 |
path.resolve用法 | 解析为绝对路径,可理解为cd命令,一层层拼接 |
禁止生成xx.js.LICENSE.txt文件 | webpack已集成TerserPlugin,new TerserPlugin({ extractComments: false,})
|
不打包js库,而通过cdn引入 | externals: { jquery: "jQuery",axios:"axios",dayjs: "dayjs",}, |
打包生成的js文件头部加上package版本号 | const packageinfo = require("./package.json"); |
依赖的node_modules不打包在使用的js文件中,而是全部打包到一个js文件中 |
splitChunks: {chunks: "all",}, 带来的问题是1个js文件过大,可采用externals优化或cacheGroups配置提取指定的module |
<h1 align="center">常见问题</h1>
错误场景 | Error Description | 解决办法 |
---|---|---|
<img width="40" height="40" src="https://cdn.worldvectorlogo.com/logos/internet-explorer-2.svg"> | Automatic publicPath is not supported in this browser |
参考官方文档、定义publicPath |
<img width="40" height="40" src="https://cdn.worldvectorlogo.com/logos/internet-explorer-2.svg"> | SCRIPT5022: SecurityError | 重启IE浏览器 |
<img width="40" height="40" src="https://cdn.worldvectorlogo.com/logos/internet-explorer-2.svg"> | ES6、Promise等语法错误 | 使用babel、target设置其编辑环境 |
<img width="30" height="30" src="https://cdn.worldvectorlogo.com/logos/chrome.svg"> <img width="30" height="30" src="https://cdn.worldvectorlogo.com/logos/internet-explorer-2.svg"> | axios请求参数中文乱码 | service.get(url,params)使用params参数,不要拼接到url后面 |
<h1 align="center">webpack配置文件</h1>
执行命令
"scripts": {
"start": "webpack serve --open --config webpack.dev.js",
"build": "webpack --config webpack.prod.js"
},
webpack.prod.js
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const TerserPlugin = require("terser-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const packageinfo = require("./package.json");
const webpack = require("webpack");
module.exports = merge(common, {
mode: "production",
target: ["web", "es5"],
optimization: {
minimizer: [
new TerserPlugin({
extractComments: false, //禁止生成注释到LICENSE.txt
}),
],
},
plugins: [
new HtmlWebpackPlugin({
title: "Production",
filename: "index.html", // 输出文件【注意:这里的根路径是module.exports.output.path】,即上面的dist
template: "./src/index.html", // 源模板文件,复制此结构的文件
hash: false,
chunks: ["index"],
}),
new webpack.BannerPlugin(`dfzq-web@version=${packageinfo.version}`),
],
});
webpack.dev.js
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
//使用环境变量,反之则使用root “/”
const ASSET_PATH = process.env.ASSET_PATH || "/";
module.exports = merge(common, {
mode: "development",
output: {
publicPath: ASSET_PATH,
},
//在webpack5版本中使用默认或者'web'参数时,hot热部署是有效的。但是编译的runtime代码IE浏览器不识别,语法不支持
//使用target: ['web','es5'],可以使编译的代码使用es5的特性,能正常在IE中使用。但是热更新失效
//webpack5热更新失效问题只能等待官方新版本中会得到优化解决,暂时建议在开发模式中使用target: 'web',在生产模式中使用target: ['web','es5']
target: ["web"], //热启动生效,IE无法识别runtime代码
devtool: "eval-source-map",
devServer: {
port: 3000,
open: true,
hot: true,
historyApiFallback: true,
allowedHosts: "all",
},
plugins: [
new HtmlWebpackPlugin({
title: "Development",
filename: "index.html", // 输出文件【注意:这里的根路径是module.exports.output.path】,即上面的dist
template: "./src/index.html", // 源模板文件,复制此结构的文件
hash: false,
chunks: ["index"],
}),
new webpack.DefinePlugin({
"process.env.ASSET_PATH": JSON.stringify(ASSET_PATH),
}),
],
});
webpack.common.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin"); // 清理dist文件夹
const webpack = require("webpack");
const CopyPlugin = require("copy-webpack-plugin"); //将单个文件或整个目录复制到构建目录
const publishPath = path.resolve(__dirname, "dfzq-office"); //生成的路径
module.exports = {
entry: {
index: path.resolve(__dirname, "./src/index.js"),
author: path.resolve(__dirname, "./src/js/author.js"),
},
output: {
filename: (chunkData) => {
const name = chunkData.chunk.name;
if (name === "excel"
) {
return "js/[name].[chunkhash:5].min.js";
} else {
return "js/[name].min.js";
}
},
path: publishPath,
},
optimization: {
//将node_modules模板分离出来,不用打包在引用的各个js里,使得体积很大
splitChunks: {
chunks: "all",
},
},
module: {
rules: [
{ test: /\.txt$/, use: "raw-loader" },
{ test: /\.(css|sass|scss)$/, use: ["style-loader", "css-loader"] },
{
test: /\.(ico|png|jpe?g|gif)$/i,
loader: "file-loader",
options: {
name: "[path][name].[ext]",
context: "src", //上下文路径,如果没有此项,dist目录下将会多一个src文件夹
},
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: {
// core-js的版本
version: 3,
},
// 需要兼容的浏览器
targets: {
chrome: "60",
firefox: "60",
ie: "9",
safari: "10",
edge: "17",
},
},
],
],
},
},
],
},
performance: { hints: false },
externals: {
jquery: "jQuery",
axios: "axios",
dayjs: "dayjs",
},
plugins: [
// 执行顺序由上至下
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [publishPath],
}),
new webpack.ProvidePlugin({
//定义全局import
$: "jquery",
jQuery: "jquery",
}),
new HtmlWebpackPlugin({
title: "作者页面",
filename: "pages/author.html",
template: "./src/pages/author.html",
hash: false,
chunks: ["author"],
}),
new CopyPlugin({
patterns: [
{
from: "./src/js/office-js",
to: "js/office-js",
},
{
from: "./src/images/",
to: "images",
},
],
}),
],
};
<h1 align="center">参考文献</h1>
Production <span id="production"></span>
https://webpack.js.org/guides/production/
publicPath
https://webpack.js.org/guides/public-path/#root
DefinePlugin
https://webpack.js.org/plugins/define-plugin/#usage
网友评论