初始化
确保本地 安装 node ,安装完成后命令行输入 node -v
查看node版本号(我本地安装的版本是14.17.0)
如果本地不同项目需要不同的node版本环境,可以点击此处下载 n 管理和切换 node 版本
node 安装好之后可以开始 webpack 之旅了!
//创建文件夹,也可以手动新建文件夹
mkdir webpack5demo
//进入文件夹
cd webpack5demo
//重点是初始化,webpack5demo 文件夹下会出现一个 package.json
npm init -y
//局部安装 webpack,webpack-cli
npm install webpack webpack-cli
基础配置
- 在package.json 同级目录(即根目录)新建
webpack.base.js
webpack.dev.js
webpack.pro.js
webpack.stage.js
等配置文件,根据自己的需要创建。- 如果需要 dev 环境下自动更新 需要在命令行执行
npm install webpack-dev-server -D
- 注意在webpack4中 dev 运行是
webpack-dev-server
,而webpack5 是webpack server
- 在 package.json 中配置一下运行方法,即 scripts, 如下配置
{
...//此处为其他配置
"scripts": {
"dev": "webpack server --config webpack.dev.js",
"build:stage": "webpack --config webpack.stage.js",
"build": "webpack --config webpack.pro.js"
},
}
1. webpack.base.js
先下载依赖
npm i webpack-merge html-webpack-plugin copy-webpack-plugin mini-css-extract-plugin css-minimizer-webpack-plugin glob-all babel-loader @babel/core @babel/polyfill @babel/preset-env ejs-loader css-loader postcss-loader postcss-preset-env autoprefixer -D
再添加配置
const path = require('path');
// 在打包目录里生成一个html文件模板,并引用入口文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 复制自定义静态资源
const CopyWebpackPlugin = require('copy-webpack-plugin');
// 提取css
const MinicssExtractPlugin = require('mini-css-extract-plugin');
// 压缩css
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const webpack = require('webpack');
//利用glob.sync实现多页面打包
const glob = require('glob-all');
//引入语言包,如果界面支持多语言的话,不需要可以直接删掉
const i18n = {
cn: require('./static/lang/cn.js'),
en: require('./static/lang/en.js'),
}
//动态设置entry,此处配置 html 相关内容
const setMPA = () => {
const entry = {};
const HtmlWebpackPlugins = [];
// 设置公共入口文件,如果不需要也可以删掉
entry['common'] = path.join(__dirname, './static/js/common.js');
// 需要将哪几个文件打包,找到需要打包的入口文件
const entryFiles = glob.sync([path.join(__dirname, './src/*/index.js')]);
// 循环每个文件,对需要特殊处理的文件进行配置
Object.keys(entryFiles).map((index) => {
const entryFile = entryFiles[index];
const match = entryFile.match(/src\/(.*)\/index\.js/);
const pageName = match && match[1];
entry[pageName] = entryFile;
//此处对多国语言进行循环处理,如果不需要对语言处理可以把这一层循环去掉,直接把HtmlWebpackPlugins.push那一段拿出来
Object.keys(i18n).map(lang => {
HtmlWebpackPlugins.push(
new HtmlWebpackPlugin({
// 打包输出文件
filename: `${pageName}/${lang}/index.html`,
// 打包依赖的源文件
template: path.join(__dirname, `src/${pageName}/index.html`),
chunks: ['common', pageName],
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
// 更多的选择: https://github.com/kangax/html-minifier#options-quick-reference
},
// 此处需要在页面里用到的参数变量都可以列在这里,不需要直接删掉
i18n: i18n[lang],
lang: lang,
})
)
})
})
// 将入口输出
return { entry, HtmlWebpackPlugins }
}
const { entry, HtmlWebpackPlugins } = setMPA();
module.exports = {
//打包入口文件路径
entry: entry,
resolve: {
alias: { //别名,不需要 jquery 可以直接删掉
'jquery': 'jquery'
}
},
//定义一些规则
module: {
//数组里每个元素为一个规则
rules: [
{
test: /\.css$/,
use: [
// webpack 是 从 后 往 前 执 行,所以要注意顺序;
// 我添加 style-loader 之后和 MinicssExtractPlugin.loader冲突,所以将 style-loader 删掉了
MinicssExtractPlugin.loader,
'css-loader',
//postcss-loader,给css代码添加一些兼容的前缀,具体配置可以添加 postcss.config.js
'postcss-loader',
]
},
{
// 对模版文件使用loader
test: /\.ejs$/,
loader: 'ejs-loader',
options: {
esModule: false,
}
},
{
test: /\.js$/,
// 具体配置可以添加 babel.config.js
use: ['babel-loader']
},
{
test: /\.(jpe?g|png|svg|gif|webp)|ico$/,
// webpack5之后可以直接使用asset处理图片,不必再配置file-loader或url-loader。
// 它是webpack5内置模块,不必额外进行安装其它东西
type: 'asset',
generator: {
filename: 'static/img/css/[name].[hash:6][ext]'
},
parser: {
dataUrlCondition: {
// 设置一个筏值20kb,小于它会执行 asset/inline, 图片转 base64;
// 大于它会执行 asset/resource 图片纯拷贝
maxSize: 20480,
}
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)/,
type: 'asset/resource',
generator: {
filename: 'static/font/[name].[hash:3][ext]'
},
}
]
},
optimization: {
minimizer: [
new CssMinimizerPlugin(),
],
},
//配置插件
plugins: HtmlWebpackPlugins.concat([
// 如果需要安装jquery,则先 npm i jquery;
// 再配置如下,不需要单独在界面里引入
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
'window.jQuery': "jquery"
}),
// 提取css
new MinicssExtractPlugin({
filename: 'static/css/[name].[hash:8].css'
}),
// // 复制自定义静态资源
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, 'static/img'), //定义要拷贝的源文件
to: 'static/img', //定义要拷贝到的目标文件夹
},
],
}),
])
};
在同级目录新增 postcss.config.js
module.exports = {
plugins: [
//添加插件autoprefixer,能加前缀
require('autoprefixer'),
require('postcss-preset-env')
]
}
在同级目录新增 babel.config.js
module.exports = {
presets: [
[
'@babel/preset-env',
]
]
}
在package.json 里配置 browserslist
{
... //其他配置
"browserslist": [
"last 5 version",
"> 1%"
]
}
2. webpack.dev.js
process.env.NODE_ENV = 'development'
const webpack = require('webpack');
const { merge } = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base')
// 配置process.env,如果不需要删除即可
const config = require('./env.config');
module.exports = merge(baseWebpackConfig, {
target: 'web',
output: { //出口文件
filename: '[name].js',
clean: true,
},
devServer: { //配置开发服务功能
// 服务器的IP地址,可以使用IP也可以使用localhost
host: '0.0.0.0',
// 服务端压缩是否开启,目前开不开都行,想关你就关
compress: true,
// 配置服务端口号,建议别用80,很容易被占用,你要是非要用也是可以的。
port: 2000,
historyApiFallback: true, //如果为 true ,页面出错不会弹出 404 页面。
hot: true, //修改或模块后,保存会自动更新,页面不用刷新呈现最新的效果。
},
plugins: [
// 配置process.env,如果不需要删除即可,
new webpack.DefinePlugin({
// 注意这里千万不能漏掉 JSON.stringify
'process.env': JSON.stringify(config)
})
]
});
webpack.pro.js
process.env.NODE_ENV = 'production'
const path = require('path');
const baseWebpackConfig = require('./webpack.base');
const { merge } = require('webpack-merge');
const webpack = require('webpack');
// 配置process.env,如果不需要删除即可
const config = require('./env.config');
module.exports = merge({
output: { //出口文件
filename: 'static/js/[name].[hash:8].js', //打包后文件名
path: path.resolve(__dirname, 'dist'), //打包后的文件路径
clean: true, // 打包会默认把上次打包内容清空后打包 webpack5.20+默认添加,替换掉旧版CleanWebpackPlugin插件
},
plugins: [
// 配置process.env,如果不需要删除即可
new webpack.DefinePlugin({
// 注意这里千万不能漏掉 JSON.stringify
'process.env': JSON.stringify(config)
})
]
}, baseWebpackConfig)
配置不同环境变量 env.config.js
// 测试环境数据
const dev = {
DocLink: "/docs/about/introduction",
StakingLink: "/Stake/activeValidators",
}
// 生产环境数据
const pro = {
DocLink: "https://docs.xxxx.io",
StakingLink: "https://xxxx.io/Stake/activeValidators",,
}
if (process.env.NODE_ENV == "production") {
var config = pro
} else {
var config = dev
}
module.exports = config