## webpack
创建webpack.config.js
webpack的配置文件,指示webpack干那些活,运行webpack指令的时候会加载其中的配置,以配置去干活
所有的构建工具都是基于nodejs平台运行的,模块化默认采用commonjs
const {resolve} = require('path');
module.exports = {
/*在这里面写webpack的配置*/
//入口起点
entry: './src/index.js', //输出
output: {
//指示输出的文件的名字
filename: 'build.js', //输出的路径
// __dirname ,node.js的变量,代表当前文件的绝对路径
path: resolve(__dirname, 'build')
}, // loader的配置
module: {
rules: [//详细的loader的配置
{
// 匹配那些文件
test: /\.css$/,
// 使用那些loader进行处理
use: [
// use数组的执行顺序,从下到上 依次执行
// 创建style标签,将js中的资源进行插入引用,添加到head中生效
'style-loader',
// 将css文件编程commonjs模块加载到css中,里面内容是样式字符串
'css-loader'
]
},
{
// 匹配那些文件
test: /\.less$/,
// 使用那些loader进行处理
use: [
// use数组的执行顺序,从下到上 依次执行
// 创建style标签,将js中的资源进行插入引用,添加到head中生效
'style-loader',
// 将css文件编程commonjs模块加载到css中,里面内容是样式字符串
'css-loader',
// 将less文件编译成css文件
'less-loader'
]
}
]
},
// plugins的配置
plugins: [
//详细的plugins配置
],
// 模式
mode: "development"
};
下载需要的loader配置 style-loader和css-loader
直接通过webpack命令运行
编写webpack-config.js
const {resolve} = require('path');
//引入html-webpack-plugin插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
//输出的filename
filename: 'build.js',
path: resolve(__dirname, "build")
},
//loader
module: {
rules: [
]
},
/*使用插件处理HTML资源,下载,引入,使用*/
plugins: [
//使用html-webpack-plugin插件,会自动创建一个空的HTML文件,并且会自动引入资源
new HtmlWebpackPlugin({
// 复制路径对应的HTML文件机构,并且自动引入资源
template:'./src/index.html'
})
],
mode: 'development'
}
;
使用插件处理HTML资源
下载插件,使用npm i html-webpack-plugin@3.2.0 -D 命令下载插件
引入插件,使用commonjs,const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
使用插件,在plugin[]中 new HtmlWebpackPlugin ();
此插件的功能:会创建一个空的HTML文件,自动引入打包输出的所有资源
但是我们需要一个有结构的HTML文件,在new HtmlWebpackPlugin ({
template:'./src/index.html
})---------->【传入参数,复制路径对应的HTML文件的结构】
配置webpack.config.js
const {resolve} = require('path');
//引入插件
let htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//入口
entry: './src/index.js',
//输入
output: {
filename: 'build.js',
path: resolve(__dirname, 'build')
},
//loader
module: {
rules: [
{
test: /\.less$/,
//使用多个loader
use: ['style-loader', 'css-loader', 'less-loader']
},
// 默认处理不了HTML中的img图片
{
test: /\.(jpg|png|gif|webp)$/,
//使用一个loader,下载url-loader 和 file-loader,因为url-loader依赖于file-loader
loader: 'url-loader',
options: {
// 如果图片大小小于8kb,就会被base64处理(8-12kb以下的图片应该给base64处理)
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片体积会更大(文件请求速度会更慢)
limit: 12 * 1024,
//url-loader是以ES6模块化解析的,而html-loader是commonjs模块化解析的
//解析时会出现问题:<img src="[object Module]" alt="小黄人">
// 解决:关闭url-loader的ES6模块化解析,使用commonJS解析
// 关闭ES6模块
esModule: false,
//如果觉得图片的名字太长,可以使用如下方法进行重命名
name: '[hash10].[ext]'
}
},
{
test: /\.html$/,
// 处理HTML文件中的img图片(负责引入img图片,从而能被url-loader处理图片)
loader: 'html-loader'
}
]
},
//插件
plugins: [
new htmlWebpackPlugin({
template: './src/index.html'
})
],
//模式
mode: 'development'
};
下载url-loader file-loader,因为url-loader依赖于file-loader
配置webpack.config.js文件
const {resolve} = require('path');
let htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
//除了这些文件
exclude: /\.(css|html|js|less)/,
loader: 'file-loader'
}
]
},
plugins: [
new htmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
注意打包字体图标需要引入对应的css文件和css文件对应的文件
使用webpack-dev-server,需要下载包
配置webpack.config.js
const {resolve} = require('path');
let htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
//除了这些文件
exclude: /\.(css|html|js|less)/,
loader: 'file-loader'
}
]
},
plugins: [
new htmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
/*
* 配置DevServer,用来自动化,就不用每次修改源代码之后都要手动重新运行webpack指令打包
* 自动编译,自动刷新浏览器,自动打开浏览器
* 特点:是在内存中编译打包,不会有任何输出
* 启动指令为:webpack-dev-server
* 因为是本地下载,要启动本地的webpack-dev-server,要使用npx webpack-dev-server
* */
devServer: {
//路径为打包后输出的路径
contentBase: resolve(__dirname, 'build'),
//启动gzip压缩
compress: true,
//端口号
port: 3000,
// 自动打开默认的浏览器
open: true
}
};
配置webpack.config.js文件
//引入绝对路径的包
const {resolve} = require('path');
//引入插件
let htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//入口文件
entry: './src/index.js', output: {
//指定js文件输出到build目录下的js下,文件名为build.js
filename: 'js/build.js', path: resolve(__dirname, 'build')
}, module: {
rules: [// 处理less文件
{
test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'],
}, // 处理css文件
{
test: /\.css$/, use: ['style-loader', 'css-loader']
}, //处理图片
{
test: /\.(gif|png|jpg|webp)$/, loader: 'url-loader', options: {
limit: 10 * 1024,
esModule: false,
name: '[hash:10].[ext]', // 指定图片资源输出到images目录下,less会编译成css文件和css文件一起输出到build.js文件中
outputPath: 'images'
}
}, // 负责引入图片
{
test: /\.html$/, loader: 'html-loader'
}, //处理其他资源
{
exclude: /\.(js|css|html|less|gif|jpg|png|webp)$/, loader: 'file-loader', options: {
outputPath: 'others'
}
}]
}, plugins: [new htmlWebpackPlugin({
template: './src/index.html'
})],
mode: 'development',
//开发环境配置
devServer: {
contentBase: resolve(__dirname, 'build'), compress: true, port: 3000
// open:true
}
};
首先要用到插件 mini-css-extract-plugin
之后引入插件
let miniCss = require('mini-css-extract-plugin');
使用插件
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html"
}),
new miniCss({
// 将提取出来的css文件输出到build/css/build.css
filename: 'css/build.css'
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
// 创建style标签将样式放入HTML文件中
// 但是此时我们需要将css文件提取出来就不需要style-loader了
// 'style-loader',
//miniCss.loader,提取js文件中的css文件为单独的文件
miniCss.loader,
'css-loader'
]
}
]
},
完整的配置
const {resolve} = require('path');
let htmlWebpackPlugin = require('html-webpack-plugin');
let miniCss = require('mini-css-extract-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 创建style标签将样式放入HTML文件中
// 但是此时我们需要将css文件提取出来就不需要style-loader了
// 'style-loader',
//miniCss.loader,提取js文件中的css文件为单独的文件
miniCss.loader,
'css-loader'
]
}
]
},
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html"
}),
new miniCss({
// 将提取出来的css文件输出到build/css/build.css
filename: 'css/build.css'
})
],
mode: 'development'
};
会对一些具有兼容问题的css样式进行处理
首先也要将css文件单独提取出来----步骤如上
需要一个postcss-loader,和postcss-preset-env插件
{
loader: "postcss-loader",
options: {
ident: 'postcss',
plugins: () => [
// postcss的插件
//帮postcss找到package.json中browserslist里面的配置,
// 通过配置加载指定的css兼容样式
/*
* "browserslist": {
"development": [
* 距离最近一个版本的谷歌浏览器
"last 1 chrome version",
* 距离最近一个版本的火狐浏览器
"last 1 firefox version"
],
"production": [
">0.2%",
* 不要死了的浏览器
"not dead",
"not op_mini all"
]
}
* */
require('postcss-preset-env')()
]
}
}
在package.json中设置
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
完整配置
const {resolve} = require('path');
let htmlWebpackPlugin = require('html-webpack-plugin');
let miniCss = require('mini-css-extract-plugin');
//设置nodejs环境变量为开发模式,因为默认会找开发模式的设置,所以这里要通过设置来改变
// process.env.NODE_ENV = 'development';
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 创建style标签将样式放入HTML文件中
// 但是此时我们需要将css文件提取出来就不需要style-loader了
// 'style-loader',
//miniCss.loader,提取js文件中的css文件为单独的文件
miniCss.loader,
'css-loader',
/*
* 处理css的兼容性问题需要一个loader和一个插件
* loader:postcss-loader
* 插件:postcss-preset-env
* */
//修改loader配置
{
loader: "postcss-loader",
options: {
ident: 'postcss',
plugins: () => [
// postcss的插件
//帮postcss找到package.json中browserslist里面的配置,
// 通过配置加载指定的css兼容样式
/*
* "browserslist": {
"development": [
* 距离最近一个版本的谷歌浏览器
"last 1 chrome version",
* 距离最近一个版本的火狐浏览器
"last 1 firefox version"
],
"production": [
">0.2%",
* 不要死了的浏览器
"not dead",
"not op_mini all"
]
}
* */
require('postcss-preset-env')()
]
}
}
]
}
]
},
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html"
}),
new miniCss({
// 将提取出来的css文件输出到build/css/build.css
filename: 'css/build.css'
})
],
mode: 'development'
};
下载插件optimize-css-assets-webpack-plugin
引入插件
let optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
使用插件
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html"
}),
new miniCss({
// 将提取出来的css文件输出到build/css/build.css
filename: 'css/build.css'
}),
//使用css压缩插件
new optimizeCssAssetsWebpackPlugin()
],
完整配置
const {resolve} = require('path');
let htmlWebpackPlugin = require('html-webpack-plugin');
let miniCss = require('mini-css-extract-plugin');
//引入压缩css插件
let optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
//设置nodejs环境变量为开发模式,因为默认会找开发模式的设置,所以这里要通过设置来改变
// process.env.NODE_ENV = 'development';
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 创建style标签将样式放入HTML文件中
// 但是此时我们需要将css文件提取出来就不需要style-loader了
// 'style-loader',
//miniCss.loader,提取js文件中的css文件为单独的文件
miniCss.loader,
'css-loader',
/*
* 处理css的兼容性问题需要一个loader和一个插件
* loader:postcss-loader
* 插件:postcss-preset-env
* */
//修改loader配置
{
loader: "postcss-loader",
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')()
]
}
}
]
}
]
},
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html"
}),
new miniCss({
// 将提取出来的css文件输出到build/css/build.css
filename: 'css/build.css'
}),
//使用css压缩插件
new optimizeCssAssetsWebpackPlugin()
],
mode: 'development'
};
压缩后的css文件
#box1{background-color:pink}#box1,#box2{display:flex;height:200px;width:200px}#box2{background-color:#ff1493}
需要的的插件和loader
rules里面的配置
{
test: /\.js$/,
//由于第三方库的代码不用检查,所以使用exclude排除第三方的库的代码
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
// 自动修复eslint的错误(会自动修改js文件的格式)
fix: true
}
package.json 里面的配置
"eslintConfig": {
"extends": "airbnb-base"
}
完整的 webpack.config 配置
const {resolve} = require('path');
let htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
/*
* 语法检查 eslint-loader eslint
*
* 只检查源代码,第三方库不用检查
*
* 在package.json里面设置检查规则
* package.json中eslintConfig中设置
*
* "eslintConfig": {
* // 继承airbnb-base
"extends": "airbnb-base"
}
*
* 使用airbnb规则需要使用到eslint-config-airbnb-base eslint-plugin-import eslint,
* 上面也要使用eslint就一起下载了
*
* */
{
test: /\.js$/,
//由于第三方库的代码不用检查,所以使用exclude排除第三方的库的代码
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
// 自动修复eslint的错误(会自动修改js文件的格式)
fix: true
}
}
]
},
plugins: [
new htmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
1.基本的js兼容性处理 --> babel-loader,@babel/preset-env
2.全部js的兼容性处理 --> @babel/polyfill
3.按需求进行兼容处理 —> core-js(推荐使用)
需要下载core-js
npm i core-js -D
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 预设,只是babel做怎么样的兼容性处理
presets: [
[
'@babel/preset-env',
{
//设置按需加载
useBuiltIns: 'usage',
corejs: {
version: 3
},
//指定兼容性做到那个版本的浏览器
targets: {
chrome: '80',
firefox: '70',
edge:'12'
}
}
]
]
}
}
完整webpack.config.js配置
const {resolve} = require('path');
let htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
/*
* js兼容性处理,需要使用 babel-loader,@babel/preset-env
*
* 1.基本的js兼容性处理 --> babel-loader,@babel/preset-env
* 存在的问题:只能转换一些基本的语法,如Promise就不能转换
* 2.全部js的兼容性处理 --> @babel/polyfill
* 存在的问题:将所有的兼容性代码引入,导致代码体积变大
* 3.按需求进行兼容处理 ---> core-js
*
* */
{
test: /\.js$/,
//排除node_modules中的文件
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 预设,只是babel做怎么样的兼容性处理
presets: [
[
'@babel/preset-env',
{
//设置按需加载
useBuiltIns: 'usage',
//指定corejs的版本
corejs: {
version: 3
},
//指定兼容性做到那个版本的浏览器
targets: {
chrome: '80',
firefox: '70',
edge:'12'
}
}
]
]
}
}
]
},
plugins: [
new htmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
生产模式下自动压缩 js 文件
mode: 'production'
使用插件html-webpack-plugin
plugins: [
new htmlWebpackPlugin({
template: './src/index.html',
// 压缩文件,至少需要两个参数
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true
}
})
],
完整配置
const {resolve} = require('path');
let htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
plugins: [
new htmlWebpackPlugin({
template: './src/index.html',
// 压缩文件,至少需要两个参数
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true
}
})
],
mode: 'development'
};
const {resolve} = require("path");
let htmlWebpackPlugin = require('html-webpack-plugin');
let miniCss = require('mini-css-extract-plugin');
//引入压缩css插件
let optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
//服用loader
const loaderCss = {
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')()
]
}
};
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
//处理less文件
{
test: /\.less$/,
use: [
// 'style-loader',
miniCss.loader,
'css-loader',
loaderCss,
'less-loader'
]
},
// 处理css文件
{
test: /\.css$/,
use: [
miniCss.loader,
'css-loader',
// 对css兼容性做处理
loaderCss
]
},
//处理图片文件
{
test: /\.(png|gif|jpg|webp)$/,
loader: 'url-loader',
options: {
// 12kb以下的图片使用base64处理
limit: 12 * 1024,
esModule: false,
name: '[hash:10].[ext]',
//指定图片资源输出到images文件夹下
outputPath: 'images'
}
},
//处理HTML文件中的图片文件
{
test: /\.html$/,
loader: 'html-loader'
},
/*
* 一般来讲,一个文件只能被一个loader处理,
* 当一个文件要被多个loader处理时,一定要指定loader的执行顺序
*
* 在这个配置中就要先执行 eslint , 在执行 babel
*
* 使用 enforce:'pre'; 优先执行
*
*
* */
//js语法检查
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
// 优先执行
enforce: 'pre',
options: {
fix: true
}
},
//js兼容性处理
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: 80,
firefox: 70,
edge: '13'
}
}
]
]
}
},
// 处理其他文件
{
exclude: /.(less|css|html|js|img|jpg|png|gif|webp)$/,
loader: 'file-loader',
options: {
outputPath: 'others'
}
}
]
},
plugins: [
// css 兼容性处理
new miniCss({
filename: 'css/build.css'
}),
// 处理HTML文件
new htmlWebpackPlugin({
template: './src/index.html',
// 压缩HTML文件
minify: {
collapseWhitespace: true,
removeComments: true
}
}),
// 压缩css文件
new optimizeCssAssetsWebpackPlugin()
],
mode: 'production'
};
开发环境优化
生产环境优化
HMR (热模块替换)
* HMR
* - 热模块替换
* - 一个模块发生变化时,只会重新打包这个模块,而不会将全部的模块重新打包,极大提高构建速度
*
* 样式文件
* - 可以使用HMR功能,是因为style-loader内部实现了
* js文件
* - 默认没有HMR功能
* -if (module.hot) {
// 监听print.js文件的变化,一旦发生变化,其他代码不会重新打包构建,会执行后面的回调函数
module.hot.accept('./print.js', function () {
// 重新将模块的行为调用
print();
});
}
* - js文件只能处理非入口文件的其他文件
* HTML文件
* - 默认没有HMR功能,而且导致HTML文件不能热更新了(HTML文件不用做HMR功能)
* - 解决:将HTML文件放入起点入口中
提供源代码到构建后代码映射技术
* source-map
* - 外部
* - 错误代码的准确信息,源代码的错误位置
*
* inline-source-map
* - 生成一个内联的source-map
* - 错误代码准确信息,源代码的错误位置
*
* hidden-source-map
* - 错误代码的错误原因,没有源代码错误的位置
* - 不能追踪源代码的错误,只能提示构建后代码的错误位置
*
* eval-source-map
* - 内联
* - 每一个文件都生成对应的source-map,都在eval
* - 错误代码准确信息,源代码的错误位置
*
* nosources-source-map
* - 外部
* - 错误代码的准确信息,但是没有任何代码信息
* cheap-source-map
* - 错误代码准确信息,源代码的错误位置
* - 不能精确到列,只能知道哪一行出错
*
* cheap-module-source-map
* - 错误代码准确信息,源代码的错误位置
* - module
*
完整配置
//引入绝对路径的包
const {resolve} = require('path');
//引入插件
let htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//入口文件
entry: ['./src/index.js', './src/index.html'],
output: {
//指定js文件输出到build目录下的js下,文件名为build.js
filename: 'js/build.js', path: resolve(__dirname, 'build')
}, module: {
rules: [// 处理less文件
{
test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'],
}, // 处理css文件
{
test: /\.css$/, use: ['style-loader', 'css-loader']
}, //处理图片
{
test: /\.(gif|png|jpg|webp)$/, loader: 'url-loader', options: {
limit: 10 * 1024, esModule: false, name: '[hash:10].[ext]', // 指定图片资源输出到images目录下,less会编译成css文件和css文件一起输出到build.js文件中
outputPath: 'images'
}
}, // 负责引入图片
{
test: /\.html$/, loader: 'html-loader'
}, //处理其他资源
{
exclude: /\.(js|css|html|less|gif|jpg|png|webp)$/, loader: 'file-loader', options: {
outputPath: 'others'
}
}]
}, plugins: [new htmlWebpackPlugin({
template: './src/index.html'
})],
mode: 'development',
//开发环境配置
devServer: {
contentBase: resolve(__dirname, 'build'), compress: true, port: 3000,
// 开启HMR功能,
// 当修改了webpack配置,新配置要生效,必须重启webpack服务
/*
* HMR
* - 热模块替换
* - 一个模块发生变化时,只会重新打包这个模块,而不会将全部的模块重新打包,极大提高构建速度
*
* 样式文件
* - 可以使用HMR功能,是因为style-loader内部实现了
* js文件
* - 默认没有HMR功能
* -if (module.hot) {
// 监听print.js文件的变化,一旦发生变化,其他代码不会重新打包构建,会执行后面的回调函数
module.hot.accept('./print.js', function () {
// 重新将模块的行为调用
print();
});
}
* - js文件只能处理非入口文件的其他文件
* HTML文件
* - 默认没有HMR功能,而且导致HTML文件不能热更新了(HTML文件不用做HMR功能)
* - 解决:将HTML文件放入起点入口中
*
* */
hot: true,
// open:true
},
devtool: 'source-map'
};
使用oneof使所有的loader只会匹配一次
完整配置
const {resolve} = require("path");
let htmlWebpackPlugin = require('html-webpack-plugin');
let miniCss = require('mini-css-extract-plugin');
//引入压缩css插件
let optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
//服用loader
const loaderCss = {
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')()
]
}
};
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
//js语法检查
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
// 优先执行
enforce: 'pre',
options: {
fix: true
}
},
{
// 以下loader只会匹配一个
// 不能有两个配置处理同一种类型的文件
// 将其中一个配置提取出去
oneOf: [
//处理less文件
{
test: /\.less$/,
use: [
// 'style-loader',
miniCss.loader,
'css-loader',
loaderCss,
'less-loader'
]
},
// 处理css文件
{
test: /\.css$/,
use: [
miniCss.loader,
'css-loader',
// 对css兼容性做处理
loaderCss
]
},
//处理图片文件
{
test: /\.(png|gif|jpg|webp)$/,
loader: 'url-loader',
options: {
// 12kb以下的图片使用base64处理
limit: 12 * 1024,
esModule: false,
name: '[hash:10].[ext]',
//指定图片资源输出到images文件夹下
outputPath: 'images'
}
},
//处理HTML文件中的图片文件
{
test: /\.html$/,
loader: 'html-loader'
},
/*
* 一般来讲,一个文件只能被一个loader处理,
* 当一个文件要被多个loader处理时,一定要指定loader的执行顺序
*
* 在这个配置中就要先执行 eslint , 在执行 babel
*
* 使用 enforce:'pre'; 优先执行
*
*
* */
//js兼容性处理
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: 80,
firefox: 70,
edge: '13'
}
}
]
]
}
},
// 处理其他文件
{
exclude: /.(less|css|html|js|img|jpg|png|gif|webp)$/,
loader: 'file-loader',
options: {
outputPath: 'others'
}
}
]
}
]
},
plugins: [
// css 兼容性处理
new miniCss({
filename: 'css/build.css'
}),
// 处理HTML文件
new htmlWebpackPlugin({
template: './src/index.html',
// 压缩HTML文件
minify: {
collapseWhitespace: true,
removeComments: true
}
}),
// 压缩css文件
new optimizeCssAssetsWebpackPlugin()
],
mode: 'production'
};
babel缓存
让第二次构建打包速度更快
开启babel缓存
cacheDirectory: true
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: 80,
firefox: 70,
edge: '13'
}
}
]
],
// 开启babel缓存
// 第二次构建时,会读取之前的缓存
cacheDirectory: true
}
},
文件资源缓存
让上线代码缓存更好使用
给文件名加上一个哈希值,使用的是webpack每次打包生成的哈希值
例
// css 兼容性处理
new miniCss({
filename: 'css/build.[chunkhash:10].css'
}),
hash:每次webpack构建时,会生成一个唯一的哈希值
chunkhash:根据chunk【Chunk是过程中的代码块】生成的哈希值。如果打包来源于同一个chunk,那么hash值就一样
contenthash,根据文件内容生成的哈希值,不同文件的哈希值一定不一样
第一种方式 ----->> 多入口的方式
每个 entry
都会在最后的打包中输出一个对应的文件。因此可以显示地进行代码分割:
entry: {
// 使用多入口的方式,来进行代码分割
add: './src/js/add.js',
reduce: './src/js/reduce.js'
},
第二种方式 ------>> splitChunks
可以将node_modules中的第三方代码单独打包成一个chunk输出
会自动分析多入口中,有没有公共的依赖,如果有会单独打包成一个chunk,不会重复打包
optimization: {
splitChunks: {
chunks: 'all'
}
},
第三种方式 ------->> 动态导入模块
在入口文件进行配置
import动态导入语法,能够将某个文件单独打包成一个chunk,将某个文件单独打包
/*
* 通过js代码,能够将某个文件单独打包成一个chunk
* import动态导入语法,将某个文件单独打包
*
* 通过 注释 webpackChunkName:'add' 的方式给打包的文件制定名字
*
*
* */
import(/* webpackChunkName:'add' */'./add').then((module1) => {
console.log(module.add(1, 2));
}).catch(() => {
console.log("加载失败");
});
import(/* webpackChunkName:'reduce' */'./reduce').then((module2) => {
module2.reduce(32, 8);
}).catch(() => {
console.log("文件加载失败");
});
懒加载
使用第三种代码分割的语法
在需要使用的时候才加载相关的资源文件
在入口文件中使用js代码进行设置
// 懒加载,只有点击的时候,add.js 文件才会加载,不使用就不会进行加载
document.getElementById('btn1').onclick = function () {
// 使用 注释webpackChunkName:'add' 指定输出文件的名字为add,
// webpackPrefetch:true , 设置预加载,等其他资源加载完毕然后在加载,但是不会显示在页面上
// 等到使用的时候在显示在页面上
import(/* webpackChunkName:'add' , webpackPrefetch:true */'./add').then((module1) => {
console.log(module1.add(1, 2));
}, (reason) => {
console.log(reason);
});
};
console.log('index.js文件被加载了');
预加载
需要使用插件workbox
引入插件
使用插件,在plugins中进行如下配置:
//PWA
new workbox.GenerateSW({
/*
1.帮助serviceworker快速启动
2.删除旧的serviceworker
- 会帮助我们生成一个serviceworker的配置文件,通过配置文件注册serviceworker
- 注册:一般是在入口的js文件中作配置
*/
clientsClaim: true,
skipWaiting: true
})
注册 serviceworker
在入口文件中配置
serviceworker 必须运行在服务器中
1.eslint 不认识window,navigator全局变量
解决:
- 修改package.json中的eslintConfig配置为:
"env": {
"browser": true // 设置支持浏览器端的全局变量
}
2.serviceworker代码必须运行在服务器上面
使用npm i serve -g 全局安装,快速生成一个简单的服务器
启动命令:serve -s build,启动服务器,将build目录下的所有资源,作为静态资源暴露出去
//注册serviceworker
//使用if判断,serviceworker 这个属性是否存在
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
// 注册serviceworker
let serviceWorkerRegistrationPromise = navigator.serviceWorker.register('/service-worker.js');
// 监听 serviceworker 是否注册成功
serviceWorkerRegistrationPromise.then(() => {
// 成功
console.log("注册成功");
}).catch((reason) => {
// 失败
console.log("注册失败");
console.log(reason);
});
});
}
需要使用thread-loader
一般是给babel-loader使用
在module中配置
使用thread-loader开启多进程打包
进程启动时间约为600ms,只有工作消耗时间比较长,才会使用多进程打包
可以使用workers来调成进程
//js兼容性处理
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
// 开启多进程打包
loader: 'thread-loader',
options: {
workers: 2 //2个进程
}
},
{
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: 80,
firefox: 70,
edge: '13'
}
}
]
]
}
}
],
},
防止将某些包打包
// 拒绝jQuery被打包进来,打包时,忽略jQuery这个库
externals: {
jquery: 'jQuery'
},
忽略后,在HTML资源中要使用,要手动进行引入
会将node_modules中的库分别打包
需要单独写一个dll配置文件
const {resolve} = require('path');
const webpack = require('webpack');
/*
* 直接运行webpack,默认运行的是webpack.config.js文件
* 而我们现在需要运行的是webpack.dll.js文件
* - 指令为:webpack --config webpack.dll.js
*
* */
module.exports = {
entry:{
// jquery --- name为jQuery
// [jQuery] --- 打包的库为jQuery
jquery:['jQuery']
},
output:{
filename:'[name].js',
path:resolve(__dirname,'dll'),
library:'[name]_[hash:5]' // 打包的库里面的内容向外暴露出去的内容叫什么名字
},
plugins:[
// 生成一个manifest.json文件,提供和jQuery的映射关系
new webpack.DllPlugin({
name:'[name]_[hash:5]', // 映射库暴露的内容的名称
path: resolve(__dirname,'dll/manifest.json') // 输出文件路径
})
],
mode:'production'
};
通过在webpack.config.js中的配置,来告诉webpack哪一些库不用打包了,引入已经打包过的库
告诉webpack不用打包哪一个库,同时使用这个库的时候,名称也要改变
const {resolve} = require('path');
const webpack = require('webpack');
/*
* 直接运行webpack,默认运行的是webpack.config.js文件
* 而我们现在需要运行的是webpack.dll.js文件
* - 指令为:webpack --config webpack.dll.js
*
* */
module.exports = {
entry:{
// jquery --- name为jQuery
// [jQuery] --- 打包的库为jQuery
jquery:['jQuery']
},
output:{
filename:'[name].js',
path:resolve(__dirname,'dll'),
library:'[name]_[hash:5]' // 打包的库里面的内容向外暴露出去的内容叫什么名字
},
plugins:[
// 生成一个manifest.json文件,提供和jQuery的映射关系
new webpack.DllPlugin({
name:'[name]_[hash:5]', // 映射库暴露的内容的名称
path: resolve(__dirname,'dll/manifest.json') // 输出文件路径
})
],
mode:'production'
};