二、Webpack配置应用
1、多页应用
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
// 多入口
entry: {
page1: './src/index1.js',
page2: './src/index2.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({ // 有两个页面,就需要 new 两次
template: './src/index1.html',
filename: 'page_1.html',
chunks: ['page1'] // [代码块] 引入对应的js文件,这个文件名是 entry 中的命名
}),
new HtmlWebpackPlugin({
template: './src/index2.html',
filename: 'page_2.html',
chunks: ['page1', 'page2']
})
]
}
项目目录:
2、source-map 源码映射
yarn add @babel/core @babel/preset-env babel-loader -D
1. source-map
源码映射,会单独生成一个sourcemap文件,代码出错会标识代码报错的列和行
2. eval-source-map
不会产生单独的文件,但是会显示报错的行和列
3. cheap-module-source-map
不会产生标识代码报错的列和行,但是是一个单独的映射文件。产生文件可以保留,用于调试,找到第几行
4. cheap-module-eval-source-map
如果有报错提示,试试使用这个:
eval-cheap-module-source-map
不会产生映射文件,也不会显示对应列,集成在打包后的文件中
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'production',
entry: {
index: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
})
],
// 第一种:源码映射,会单独生成一个sourcemap文件,代码出错会标识代码报错的列和行
// devtool: 'source-map', // 增加映射文件,可以便于调试源码
// 第二种:不会产生单独的文件,但是会显示报错的行和列
// devtool: 'eval-source-map',
// 第三种:不会产生标识代码报错的列,但是是一个单独的映射文件。产生文件可以保留,用于调试,找到第几行
// devtool: 'cheap-module-source-map',
// 第四种:不会产生映射文件,也不会显示对应列,集成在打包后的文件中
devtool: 'eval-cheap-module-source-map',
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}
3、Watch 实时打包
实时打包,不需要每次修改代码后手动打包。
// webpack.config.js
module.exports = {
// ...
watch: true,
watchOptions: { // 监控的选项
poll: 1000, // 每秒问我们1000次是否需要打包
aggregateTimeout: 500, // 防抖:500ms内一直操作,500ms后还没有操作就打包
ignored: /node_modules/ // 不需要监控哪个文件
}
// ...
}
4. Webapck插件的应用
1. clean-webpack-plugin 打包前先清空当前打包目录下的文件
参考链接:clean-webpack-plugin
// webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
// ...
plugins: [
new CleanWebpackPlugin()
],
// ...
}
2.copy-webpack-plugin 拷贝一些静态文件到打包目录下
参考链接:copy-webpack-plugin
通常会用于拷贝一些静态文件到打包目录下
// webpack.config.js
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
// ...
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: './doc', to: './doc'}
]
})
],
// ...
}
3. bannerPlugin 版权声明
这是Webpack内置的插件
参考链接:bannerPlugin
// webpack.config.js
const Webpack = require('webpack');
module.exports = {
// ...
plugins: [
new Webpack.BannerPlugin('Made my Hanshin')
]
// ...
}
5、跨域处理
// webpack.config.js
module.exports = {
// ...
devServer: {
proxy: {
// '/api': 'http://localhost:3000'
'/api': {
target: 'http://localhost:3000',
pathRewrite: {
'/api': ''
}
}
}
}
// ...
}
6、MOCK数据,仅前端模拟数据
// webpack.config.js
module.exports = {
// ...
devServer: {
before(app) {
app.get('/api', (req, res) => {
res.json({
key: 'hello world'
})
})
}
}
// ...
}
7、有服务端,在服务端中启动webpack,端口使用服务端端口
前后端启动在一起,如下,访问
localhost:3000
即可node server.js 即可
// server.js
const express = require('express');
const app = express();
const webpack = require('webpack');
// 需要中间件
const middle = require('webpack-dev-middleware');
const config = require('./webpack.config');
const compiler = webpack(config);
app.use(middle(compiler));
app.get('/api', (req, res) => {
res.json({
key: 'hello world111'
})
})
app.listen(3000);
8、Webpack解析第三方包
1. 解析引用模块
解析的欧快可能都来源于第三方包。
commonJS 规范:先找当前目录下的 node_modules,找不到在往上找。
所以我们可以配置强制在当前目录找。
// webpack.config.js
module.exports = {
// ...
resolve: {
modules: [path.resolve('node_modules')]
}
// ...
}
2. 样式文件的引入,如bootatrap
- 方案一:
// index.js
import 'bootstrap' // 只这样写不做配置是不会生效的,会默认去找js文件
import 'bootstrap/dist/css/bootstrap.css' // 这样写是生效的
可以这样处理:
- 方案二:
// index.js
import 'bootstrap'
// webpack.config.js
module.exports = {
// ...
resolve: {
alias: { // 别名
bootstrap: 'bootstrap/dist/css/bootstrap.css'
}
}
// ...
}
- 方案三:
// index.js
import 'bootstrap'
// webpack.config.js
module.exports = {
// ...
resolve: {
mainFields: ['style', 'main'] // 主入口的字段,从左往右找,找不到再往右找
}
// ...
}
这个 mainFields 对应 bootstrap 下面的
package.json
中的style 、 main 这些key。
mainFiles
// webpack.config.js
module.exports = {
// ...
resolve: {
// 入口文件名,未指定默认找index.js。如果指定了,从左往右找,直到找到为止
mainFiles: ['index1', 'index']
}
// ...
}
3. css等文件的引入
- 方案一:
// index.js
import './style.css'
- 方案二:
为了方便,可以这样引入:
// index.js
import './style'
// webpack.config.js
module.exports = {
// ...
resolve: {
// import文件的时候如果没写后缀,自动补充后缀,从左往右,直到找到这个文件为止
extensions: ['.js', '.css', '.json']
}
// ...
}
9、Webapck 定义环境变量及不同环境的处理
下面这样是错误的,会提示 dev 未定义:
// index.js
console.log(DEV);
// webpack.config.js
const Webpack = require('webpack');
module.exports = {
// ...
plugins: [
new Webpack.DefinePlugin({
DEV: 'dev'
})
]
// ...
}
可以这样处理:
// index.js
console.log(DEV); // 'dev'
console.log(PRO); // 'PRO'
console.log(NUM); // 2
console.log(TYPE); // true
// webpack.config.js
const Webpack = require('webpack');
module.exports = {
// ...
plugins: [
new Webpack.DefinePlugin({
DEV: "'dev'",
PRO: JSON.stringify('PRO'),
NUM: '1+1',
TYPE: 'true'
})
]
// ...
}
我们可以通过不同文件来区分不同的环境:
新建各自的配置文件 webpack.base.js
, webpack.pro.js
,webpack.dev.js
安装插件:yarn add webpack-merge -D
// webpack.base.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
}),
new CleanWebpackPlugin()
],
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}
// webpack.dev.js
const { merge } = require('webpack-merge');
const base = require('./webpack.base.js');
const Webpack = require('webpack');
module.exports = merge(base, {
mode: 'development',
plugins: [
new Webpack.DefinePlugin({
ENV: JSON.stringify('development')
})
]
})
// webpack.pro.js
const { merge } = require('webpack-merge');
const base = require('./webpack.base.js');
const Webpack = require('webpack');
module.exports = merge(base, {
mode: 'production',
plugins: [
new Webpack.DefinePlugin({
ENV: JSON.stringify('production')
})
]
})