一、项目初始化
npm init -y
npm install --save-dev webpack
npm install webpack-cli -D
创建 webpack.config.js文件 在文件中输入代码:
let path=require("path")//引用node核心模块 => 路径
module.exports={
mode:"production", //打包后文件模式 两种 => development production
entry:'./src/index.js',//入口文件位置
output:{
filename:'bundle.[hash:8].js', //文件名称
path:path.resolve(__dirname,"dist"),//打包后的文件地址为绝对路径 名称为’dist'
publicPath:''//给所有打包文件引入时加前缀,包括css、js、img,如果只想处理图片可以单独在url-loader配置中加publicPath
}
}
运行:
npx webpack
【可选】在package.json文件中 ,添加脚本代码如下:
"scripts":{
"build":"webpack --config webpack.config.my.js"//可以操作重命名后的webpack.config.js文件
}
运行:
npm run build
二、本地服务
使用简单的服务插件 webpack-dev-server, 在内存中启动
npm install webpack-dev-server -D
运行:
npx webpack-dev-server
[可选] 在webpack.config.js文件中添加服务代码:
devServer:{//开发服务器配置
port:3000,//端口号
progress:true,//是否显示进度条
contentBase:'./dist',//服务器启动的位置
open:true,//自动打开浏览器
compress:true//gzip压缩
hot:true//启动热更新
}
【可选】在package.json文件中加入代码:
"scripts":{
"dev":"webpack-dev-server --open"//添加 --open 自动打开浏览器
}
运行:
npm run dev
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9tnQ7kg3-1616136915365)(C:\Users\jfq\AppData\Roaming\Typora\typora-user-images\1614309130932.png)]
此报错解决方案:
npm uninstall -D webpack-cli
npm install -D webpack-cli@3
三、loader
- loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript);
- loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块
在webpack.config.js文件中配置代码:
module.exports = {
module: {//模块
rules: [//规则
{ test: /\.css$/, use: 'css-loader' }
]
}
};
推荐使用yarn 进行安装
3.1 处理CSS
包括css less sass 必须在js文件中导入 import '.css’
3.1.1 处理css文件
1、安装 style-loader css-loader 模块
npm install style-loader css-loader -D
2、在webpack.config.js文件中配置代码:
//css-loader 用来解析@import这种语法
//style-loader 用来把css插入 header 标签中
//loader的执行顺序:默认是从右向左,从下向上
module.exports={
module:{
rules:[
//{test:/\.css$/,use:['style-loader','css-loader']}//use可以写成string array object
{
test:/\.css$/,
use:[{
loader:"style-loader",
options:{
insertAt:"top"//将css放到body上面;1.0版本已经放弃;现在不使用
}
},
"css-loader"
]
}
]
}
}
3.1.2 处理less文件
1、安装 style-loader css-loader less-loader 模块 和 less 模块
npm install style-loader css-loader less-loader -D
2、在webpack.config.js文件中配置代码:
module.exports={
module:{
rules:[
{
test:/\.less$/,
use:[
{
loader:"style-loader",
},
"css-loader",
"less-loader"
]
}
]
}
}
3.1.3 处理sass文件
- 安装style-loader css-loader sass-loader 模块 和 sass 模块
- 用法跟less一样;
3.1.4 css兼容处理
1、安装 “postcss-loader autoprefixer” 模块
yarn add postcss-loader autoprefixer -D
2、postcss 需要配置文档 postcss.config.js
module.exports = {
plugins: {
// 兼容浏览器,添加前缀
'autoprefixer':{
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8"
//'last 10 versions', // 所有主流浏览器最近10版本用
],
grid: true
}
}
}
3、在 “webpack.config.js”文件中添加配置:
// css
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
}
// less
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'less-loader'
]
},
3.2 处理JS
3.2.1 ESLint语法检测
npm install eslint-config-airbnb-base eslint-plugin-import eslint eslint-loader -D
webpack.config.js中配置
/*
eslint语法检查:eslint-loader eslint
注意:只检查自己的js代码,第三方的库是不用检查的
设置检查规则:
packag.json中eslintConfig中设置~
"eslintConfig":{
"extends":"airbnb-base"
}
aribnb --> eslint-config-airbnb-base eslint-plugin-import eslint
*/
{
test:/\.js$/,
exclude:/node_modules/,
loader: 'eslint-loader',
options:{
fix:true//eslint自动修复格式错误
}
}
3.在package.json中配置eslintConfig
"eslintConfig": {
"extends": "airbnb-base"
}
4.如果配置完成后,打包时出现Resolve error: unable to load resolver “node” src\main.js:1:1 错误,请安装下面的依赖后再打包
npm install eslint-import-resolver-node -D
3.2.2 JS兼容处理
因为es6语法不兼容部分浏览器,所以要对项目进行配置
1.安装依赖
npm install babel-loader @babel/preset-env @babel/core core-js -D //第一三方法安装这个
npm install @babel/polyfill -D //第二个方法安装这个
2.三种方法兼容
(1)babel-loader @babel/preset-env @babel/core 兼容
只能兼容基本的语法,但是像是promise语法,无法进行兼容
(2)兼容全部js语法 @babel/polyfill
在index.js中引入依赖即可
import '@babel/polyfill’
缺点:全部兼容造成打包文件太大
(3)core-js 配合第一种进行按需兼容
3.配置详情(下面是将eslint检查与js兼容配置放在了一起,module中不可以对.js文件(同一种文件)进行多次匹配,多次匹配只会匹配第一个,所以要结合在一起)
{
test:/\.js$/,
exclude:/node_modules/,
use:[
//要优先执行eslint-loader,可使用配置enforce:'pre'
{
loader: 'eslint-loader',
options:{
fix:true//eslint自动修复格式错误
}
},
//js兼容性处理:babel-loader @babel/preset-env @babel/core
{
loader: 'babel-loader',
options:{
//预设:指示babel做怎么样的兼容性处理
presets:[
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: {
version: 3,
},
// 指定兼容浏览器版本范围
targets: {
chrome: '70', // 谷歌版本70及以上
firefox: '62',
ie: '9',
safari: '10',
edge: '17',
}
}
]
]
}
}
]
},
所以一般采用第一种加第三种组合进行.js文件兼容,也就是上面贴的代码。
第二种具体引入方式如下,不建议使用
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
}
3.3 处理其他文件
3.2.1 处理路径
- 安装 file-loader 插件 可以处理 图片、字体等
npm install --save-dev file-loader
- 在webpack.config.js文件中添加代码配置:
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/, //图像的格式,也可以判断字体文件/\.(woff|woff2|eot|ttf|otf)$/
use: [
'file-loader'
]
}
]
}
};
*解析html 中的img 如
yarn add html-loader -D
{
test: /\.html$/,
use: 'html-loader'
}
3.2.2 当图片小于多少,用base64编码
yarn add url-loader -D
//如果过大,才用file-loader
{
test: /\.(png|jpg|gif)$/,
// 当图片小于多少,用base64,否则用file-loader产生真实的图片
use: {
loader: 'url-loader',
options: {
limit: 200 * 1024, // 小于200k变成base64
}
}
}
3.2.3 打包分类
1.图片分类
{
test: /\.(png|jpg|gif)$/,
// 当图片小于多少,用base64,否则用file-loader产生真实的图片
use: {
loader: 'url-loader',
options: {
limit: 1, // 200k 200 * 1024
outputPath: 'img/' // 打包后输出地址 在dist/img
}
}
},
2.css分类
plugins: [
new MiniCssExtractPlugin({
filename: 'css/main.css'
}),
]
3.希望输出的时候,给这些css、img 加上前缀,传到服务器也能访问:
output: {
filename: 'bundle.[hash:8].js', // [hash:8] 只显示8位hash
path: path.resolve(__dirname, 'dist'),
publicPath: 'http://www.' // 给静态资源统一加
},
如果只处理图片路径:
{
test: /\.(png|jpg|gif)$/,
// 当图片小于多少,用base64,否则用file-loader产生真实的图片
use: {
loader: 'url-loader',
options: {
limit: 1, // 200k 200 * 1024
outputPath: '/img/', // 打包后输出地址
publicPath: 'http://www.'
}
}
}
四、插件[plugins]
4.1html-webpack-plugin
使用'html-webpack-plugin’插件自定义打包html文件
npm install html-webpack-plugin -D
在webpack.config.js文件中,添加配置代码:
const htmlWebpackPlugin = require('html-webpack-plugin')//引入插件
plugins:[//放置所有的webpack插件
new htmlWebpackPlugin({//用于使用模板打包时生成文件
template:'',//模板文件
filename:'',//打包后生成的文件
hash:true,//添加hash值解决缓存问题
minify:{
removeAttributeQuotes:true,//删除属性双引号
collapseWhitespace:true//折叠空行变为一行
}
})
]
4.2 mini-css-extract-plugin
抽离css样式,成单独文件
npm install mini-css-extract-plugin -D
在webpack.config.js中配置:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 压缩css
module.exports={
plugins: [
new MiniCssExtractPlugin({
filename: 'css/main.css'//输出文件名
})
],
module:{
rules:[
{
test: /\.css$/, // css 处理
use: [
// {
// loader: 'style-loader',
// },
// 此时不需要style-loader
MiniCssExtractPlugin.loader, // 抽离
'css-loader', // css-loader 用来解析@import这种语法,
'postcss-loader'
]
}
]
}
}
4.3 压缩css,js代码
yarn add optimize-css-assets-webpack-plugin -D
yarn add uglifyjs-webpack-plugin -D
2、在webpack.config.js文件中配置代码:
// 用了`mini-css-extract-plugin`抽离css为link需使用`optimize-css-assets-webpack-plugin`进行压缩css,使用此方法压缩了css需要`uglifyjs-webpack-plugin`压缩js
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")//压缩css
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")//压缩js
module.exports = {
optimization: { // 优化项
minimizer: [
new UglifyJsPlugin({ // 优化js
cache: true, // 是否缓存
parallel: true, // 是否并发打包
// sourceMap: true // 源码映射 set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({}) // css 的优化
]
},
mode: 'production',
entry: '',
output: {},
}
五、配置优化项
5.1 模块热更新(HMR)
只存在于开发环境,哪块更新只更新那块
- 配置热更新,在devServer中配置hot,开启HMR功能
devServer:{
contentBase: resolve(__dirname,'build'),//自动构建目录,打包后的文件夹
compress:true,
port:3000,
open:true,
hot:true//开启热更新
}
此时样式文件已经可以实现热更新,因为style-loader内部实现了,但是js和html文件会出现问题。
(1)解决html文件问题,将entry改为数组,引入index.html文件,
html文件:默认不能使用HMR功能,同时会导致问题:html文件不能热更新(不用做HMR功能)
entry:['./src/index.js','./src/index.html'],
(2)解决js文件问题,配置js文件
js文件:默认不能使用HMR功能 --需要修改js代码,添加支持,入口js文件是没法处理的,这里处理非入口的print.js文件
import print from './print'
print();
if(module.hot){
//一旦 module.hot 为true,说明开启了HMR功能。 -->让HMR功能代码失效
module.hot.accept('./print.js',function(){
//方法会监听 print.js文件变化,一旦发生变化,其他模块不会重新打包构建。
//会执行后面的回调函数
print();
})
}
5.2调试工具(devtool)
利于代码调试,显示报错准确行数;
devtool: 'source-map' //cheap-module-souce-map
参数介绍
/**
* source-map :一种提供源代码到构建后代码的映射技术(如果构建后代码出错,可以通过映射追踪源代码错误)
* [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
*
* 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会将loader的source map加入
*
* 内联 和 外部的区别:1.外部生成了文件,内联没有 2.内联构建速度更快
*
* 开发环境:速度快,调试更友好
* 速度快(eval>inline>cheap>...)
* eval-cheap-source-map
* eval-source-map
* 调试更友好
* souce-map
* cheap-module-source-map
* cheap-source-map
*
* --> eval-source-map 调试更友好/ eval-cheap-module-source-map 性能更好
*
* 生产环境:源代码要不要隐藏?调试要不要更友好
* 内联会让代码体积变的非常大,所以在生产环境中不使用内联
* nosources-source-map 代码全部隐藏
* hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
*
* -->source-map / cheap-module-souce-map
*/
react项目中devtool配置如下
devtool: isEnvProduction
? shouldUseSourceMap
? 'source-map'
: false
: isEnvDevelopment && 'cheap-module-source-map',
5.3 提高匹配效率 oneOf
提高loader匹配效率,使用方法如下,匹配到一个loader后,后面的就不会再继续匹配了。
注意:不能有两个配置处理同一种类型文件
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
// //优先执行
enforce:'pre',
loader:'eslint-loader',
options:{
fix:true
}
},
{
//下面的loader只会匹配一个,处理性能更好
//注意:不能有两个配置处理同一种类型文件
oneOf:[
{
test:/\.css$/,
use:[...commenCssLoader]
},
{
test:/\.less$/,
use:[...commenCssLoader,'less-loader']
},
]
}
]
},
5.4 babel缓存
不用重新加载所有的文件,用户第二次进入页面的时候直接读取缓存
- 在匹配.js文件的loader中写入配置cacheDirectory
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
presets:[
[
'@babel/preset-env',
{
useBuiltIns:'usage',
corejs:{version:3},
targets:{
chrome:'70',
firefox:'62',
ie:'9',
safari:'10',
edge:'17',
}
}
]
],
//开启babel缓存
//第二次构建时,会读取之前的缓存
cacheDirectory:true
}
},
- 给输出的js文件还有css文件设置打包输出名称
output:{
filename:'js/build.[contenthash:10].js',
path:resolve(__dirname,'build')
},
new MiniCssExtractPlugin({
filename:'css/build.[contenthash:10].css'
}),
配置详情
/**
* babel缓存
* cacheDirectory:true
* 文件资源缓存
* hash:每次webpack构建时会生成一个唯一的hash值。
* 问题:因为js和css同时使用一个hash值。
* 如果重新打包,会导致所有缓存失效。(可能只改变了一个文件)
* chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
* 问题:js和css的hash值还是一样的。因为css是在js中被引用的,两个同属一个chunk
* contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样
*/
5.5 tree shaking(树摇)
去除无用代码(未使用的代码)
自动开启条件:
- 必须使用es6模块化。
- 开启mode:production环境。
- 在package.json中配置sideEffects
/**
* tree shaking(树摇):
* 去除无用代码(未使用的代码)
* 自动开启条件:1.必须使用es6模块化。2.开启mode:production环境。
* 作用:减少代码体积
*
* 在package.json中配置
* "sideEffects":false 所有代码都没有副作用 (都可以进行tree shaking)
* 问题:可能会把css/ @babel/polyfill (副作用)文件干掉
* 解决:
* "sideEffects":["*.css"]
*/
六、打包多页应用
// 多入口
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
home: './src/index.js',
other: './src/other.js'
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
filename: 'home.html',
chunks: ['home']
}),
new HtmlWebpackPlugin({
template: './index.html',
filename: 'other.html',
chunks: ['other', 'home'] // other.html 里面有 other.js & home.js
}),
]
}
来源:https://www./content-4-897351.html
|