webpack配置介绍
第一章、webpack环境配置
1、安装node
2、创建package.json文件
命令:npm init
3、安装webpack
本地安装(推荐):
npm install --save-dev webpack
npm install --save-dev webpack-cli
全局安装
npm install --global webpack webpack-cli
4、打包
默认entry入口:src/index.js
默认outPut出口:dist/main.js
打包模式
webapck --mode developement
webapck --mode production
第二章、配置config文件
一、配置出入口
1、新建一个webpack.config.js
2、配置入口entry(所需打包的文件路径)
3、配置出口output
entry: './public/index.js', output: { path: path.resolve(__dirname, '../build'), filename: 'bundle[hash].js' },
(1)path指文件打包后的存放路径
(2)path.resolve()方法将路径或路径片段的序列处理成绝对路径
(3)__dirname表示当前文件所在的目录的绝对路径
(4)filename是打包后文件的名称
二、配置本地服务器(webpack-dev-server)
1、安装
npm insatll --save-dev webpack-dev-server
2、配置webpack.config.js
devServer: { contentBase: './build',//设置服务器访问的基本目录 host: 'localhost',//服务器的ip地址 port: 8080,//端口 hot: true,//开启热模块替换 hotOnly: true, },
3、配置package.json
"scripts": { "start": { "webpack-dev-serve --mode development" } }
第三章、配置loader
loade让webapck能够去处理那些非JavaScript文件(webpack自身只理解JavaScript)。loader可以将所有类型文件转换为webpack能够处理的有效模块,然后你可以利用webpack的打包能力,对它们进行处理。
一、编译css
1、安装loader
2、安装style-loader和scc-loader
npm install style-loadercss-loader --save-dev
3、配置loader
在webpack.config.js的modules中的rules中配置
在webpack的配置loader有两个目标
(1)、test属性:用于标识出应该呗对应的loader进行转换的某个或某些文件。
(2)、use属性:表示转换时,应该使用哪个loader。
{ test: /\.css$/, use: ['style-loader', { loader: 'css-loader', options: { sourceMap: true } }] }
二、编译less和sass
1、写法、
编译前:
@width: 10px; @height: @width + 10px; #height: { width: @width; height: @height; }
编译后:
#height: {
width: 10px;
height: 20px;
}
2、安装loader
安装less-loader 和 less
npm install less-loader less --save-dev
3、配置loader
在webpack.config.js中的module中增加以下规则:
rules:[ { test: /\.less$/, use: ['style-loader', ;css-loader', 'less-loader'] } ]
四、编译sass和sass
1、处理效果:
2、安装loader
安装sas-loader 和 node-sass
npm install sass-loader node-sass --save-dev
3、配置loader
rules:[ { test: /\.scss$/, use: ['style-loader', ;'css-loader', 'sass-loader'] } ]
五、使用PostCss处理浏览器前缀
1、处理效果
2、安装loader
安装postcss-loader 和 autoprefixer
npm install --save-dev postcs-loader autoprefixer
3、配置loader
需要和autoprefixer一起使用
rules:[ { test: /\.scss$/, use: ['style-loader', ;css-loader', 'sass-loader', { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer')({ browsers: [ 'ie >= 8',//ie版本大于等于ie8 'Firefox >= 20',//火狐浏览器大于等于20版本 'Safari >= 5',//safari大于等于5版本 'Android >= 4',//版本大于等于Android4 'Ios >= 6',//版本大于等于iOS6 'last 4 version',//浏览器最新的四个版本 ] }) ] } }] } ]
或者在package.json里面加上下面设置
"browserslist": [ "ie >= 8",//ie版本大于等于ie8 "Firefox >= 20",//火狐浏览器大于等于20版本 "Safari >= 5",//safari大于等于5版本 "Android >= 4",//版本大于等于Android4 "Ios >= 6",//版本大于等于iOS6 "last 4 version",//浏览器最新的四个版本 ]
第四章、文件处理
一、文件处理
1、安装loader
flie-loader
npm install --save-dev file-loader
2、配置config文件
{ test: /\.(png|jpg|gif|jpeg)$/, use: 'file-loader' }
3、选项配置
(1)配置option
name:为你的文件配置自定义的文件名模板(默认值[hash].[ext])
context:配置自定义文件的上下文,默认为 webpack.config.js
publicPath: 为你的文件配置自定义public发布目录
outputPath:为你的文件配置自定义output输出,目录
二、字体文件处理
1、下载字体文件
以bootstrap字体文件为例子
Bootstrap字体文件下载地址:https://v3.bootcss.com/getting-started/
2、配置config文件
{ test: /\.css$/, use: ['style-loader', 'caa-loader'] }, { test: /\.(ttf|woff|woff2|eot|svg)$/, use: [{ loader: 'file-loader', options: { outputPath: 'fonts/' } }] }
三、第三方js库处理
以jquery库为例
1、本地导入:
第一种方式:编写配置文件
webpack.config.js中
const webpack = require('webpack') resolve: { alias: { jQuery: path.resolve(__dirname, 'public/js/jquery.min.js') } }, plugins: [ new webpack.ProvidePlugin({ jQuery: 'jQuery' }) ]
第二种方式:npm安装模块
安装jQuery库
npm install jquery --save-dev
直接在js里面import引入
import $ from 'jquery'
四、使用babel编译es6
1、了解babel
2、安装依赖
npm install babel-loader @babel/core @babel/preset-env --save-dev
3、配置config文件
exclude表示不在指定文件查找相关文件
{ test: /\.js$/, exclude: // use: ['babel-loader'] }
4、新建.babelrc文件配置转换规则
{ "presets": ["@babel/preset-env"] }
另一种配置规则
{ test: /\.js$/, exclude: // use: { loader: 'bable-loader', options: { presets: ["@babel/preset-env"] } } }
第四章、插件配置
一、生成HTML(html-webpack-plugin)
2、安装依赖
npm install html-webpack-plugin --save-dev
3、配置configwenjian
在webpack.config.js中
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //... plugins: [ //... new HtmlWebpackPlugin({ template: "./public/index.html",//模板文件位置 filename: "webpack.html"//打包后的文件名 minify: { minimize: true,是否打包为最小值 removeAttributeQuotes: true,//去除引号 removeComments: true,//去除注释 collapseWhitespace: true,//去除空格 minifyCSS: true,//压缩html内的样式 minifyJS: true,//压缩html内的js removeEmptyElements: true, //清楚内容为空的元素 }, hash: true,//引入产出资源时加上哈希避免缓存 }) ] }
二、提取分离CSS
第一种:使用ExtractTestPlugin插件
1、安装
npm install --save-dev extra-text-webpack-plugin@next
2、配置config文件
const ExtractTestPlugin = require('extract-test-webpack-plugin'); module.exports = { //... rules: [ //... { test: /\.css$/, use: ExtractTestPlugin.extract({ fallback: "style-loader",//表示编译后用什么loader来提取css文件 use: "css-loader" }) } ], plugins: [ //... new ExtractTestPlugin("./css/[name].css"), //打包后的文件路径及文件名,可以打包在一个文件内 ] }
第二种:mini-css-extract-plugin插件
1、安装
npm install --save-dev mini-css-extract-plugin
2、config配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { //... rules: [ //... { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] } ], plugins: [ //... new MiniCssExtractPlugin({ filename: "./css/[name].css" }) ] }
三、压缩css及优化css结构
1、处理效果
2、optimize-css-assets-webpack-plugin 插件
(1)安装
npm install --save-dev optimize-css-assets-webpack-plugin
(2)配置config文件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { //... plugins: [ //... new OptimizeCssAssetsWebpackPlugin({ assetNameRegExp: /\.css$/g, cssProcessor: require("cssnano"), cssProcessorPluginOptions: { preset: ['default', { discardComments: { removeAll: true } }] }, canPrint: true }) ] }
四、拷贝静态文件
1、处理效果
2、安装
npm install --save-devcopy-webpack-plugin
3、配置config文件
const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { //... plugins: [ //... new CopyWebpackPlugin([ { from: __dirname + '/public/assets',//项目中静态资源的路径 to: __dirname + '/build/assets'//打包后静态资源拷贝到的路径 } ]) ] }
五、用clean-webpack-plugin清除文件
1、处理效果
当我们修改带hash的文件并进行打包时,梅打包一次就会生成一个新的文件,而旧的文件并没有删除
为了解决这个问题,我们可以使用clean-webpack-plugin在打包之前将文件先清除,之后再打包出新的文件。
2、安装
npm install --save-dev clean-webpack-plugin
3、配置config文件
const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { //... plugins: [ new CleanWebpackPlugin(['build']),//需要写在前面 //... ] }
六、webpack处理HTML中引入图片
1、处理效果
未使用loader时, 会出现路径错误,图片不显示的情况
经过loader处理后,图片能正常显示
2、安装loader
npm install --sace-dev html-loader
3、配置config文件
module.exports = { //... rules: [ //... { test: /\.(html)$/, use: [{ loader: 'html-loader', options: { attrs: ['img:src', 'img:data-src'] } }] } ] }
第五章、调试
一、使用sourcemap调试
1、了解sourcemap
Sourcemap是为了解决实际运行代码(打包后)出现问题时无法定位到开发环境中的源代码的问题。
devtool选项
5个基本类型
(1)evel
每个模块都是用evel()执行,每一个模块后增加sourceURL来关联处理前后的对应关系,如下图:
由于会映射转换后的代码,而不是映射到原始代码(没有从loader中获取source map),所以不能正确的显示行数,因为不需要生成模块的sourcemap,因此打包的速度很快。
(2)source-map
source-map会为模块生成独立的sourcemap文件。
打包后的模块在模块后面会对应应用一个.map文件,同时在打包好的目录下会生成相应的,map文件。如下图:
(3)inline
与source-map不同,增加inline属性后,不会生成独立的.map文件,source-map转换为DataUrl后添加到bundle中,如下图所示:
(4)cheap
cheap属性在打包后同样为每一个模块生成.map文件,但是与source-map的区别在于cheap生成的.map文件会忽略原始代码中的列表信息,也不包含loader的sourcemap。
(5)module
包含了loader模块之间的sourcemap,将loader source-map简化为每行一个映射。
2、sourcemap调试
(1)js调试
(2)css调试
二、webpack开发调试(模块热替换)
(1)了解模块热替换
模块热替换(HMR-Hot Model Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面,主要是通过以下几种方式,来先注加快开发速度:
-
- 保留在完全重新加载页面时丢失的应用程序状态。
- 只更新变更内容,以节省宝贵的开发时间。
- 调整样式更加迅速,直接相当于在浏览器中更改样式。
(2)配置config
Plugin配置
NamedModulesPlugin:当开启HMR的时候使用该插件会显示模块的相对路径。
(3)其他配置
devServe中加入hotOnly表示只有热更新, 不会自动刷新页面,
修改js文件时代码不会自动热更新,需要在js文件中加入以下代码可以告诉webpack接受热更新的模块
三、区分开发环境和生产环境
(1)简单了解
开发环境和生产环境的构建目标差异很大, 在开发环境中,我们需要具有强大的、具有实时重新加载或热模块替换能力和localhost server。而在生产环境中,我们的目标则转向与更小的bundle,以及资源的优化,以改善加载时间。所以我们通常建议为每个环境编写彼此独立的webpack配置。
(2)安装
npm install --save-dev webpack-merge
(3)配置
a、拆分文件
在这里我们可以将webpack。config.js拆分为三个文件,分别是webpack.common.conf.js、webpack.dev.conf.js、webpack.prod.conf.js。
webpack.common.conf.js 是放一些我们公用的配置,比如入口entry、出口output、常用loader及插件等。
webpack.dev.conf.js 是在开发环境上的配置,比如devServer配置、热模块替换等方便开发的配置。
webpack.prod.conf.js 是在生产环境上的配置,比如提取分离css、压缩css和js等。
webpack.common.conf.js文件配置
const path = require('path') const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin')//生成HTML module.exports = { entry: './public/index.js', output: { path: path.resolve(__dirname, '../build'), filename: 'bundle[hash].js' }, modules: { rules: [ { test: /\.css$/, use: ['style-loader', { loader: 'css-loader', options: { sourceMap: true } }] }, // { // test: /\.css$/, // use: ExtractTestPlugin.extract({ // fallback: "style-loader",//表示编译后用什么loader来提取css文件 // use: "css-loader" // }) // }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader']//表示编译后用什么loader来提取css文件 }, { test: /\.scss$/, use: ['style-loader', ;'css-loader', 'sass-loader', { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer')({ browsers: [ 'ie >= 8',//ie版本大于等于ie8 'Firefox >= 20',//火狐浏览器大于等于20版本 'Safari >= 5',//safari大于等于5版本 'Android >= 4',//版本大于等于Android4 'Ios >= 6',//版本大于等于iOS6 'last 4 version',//浏览器最新的四个版本 ] }) ] } }] }, { test: /\.less$/, use: ['style-loader', ;'css-loader', 'less-loader'] }, { test: /\.(png|jpg|gif|jpeg)$/, use: [{ loader: 'file-loader', options: { name: '[hash]xxxx.jpg', outputPath: './image' } }] }, { test: /\.js$/, exclude: /node_modules/,//忽略掉的文件目录 use: { //使用babel编译es6 loader: 'bable-loader', options: { presets: ["@babel/preset-env"] } } }, { //webpack处理HTML中引入图片 test: /\.(html)$/, use: [{ loader: 'html-loader', options: { attrs: ['img:src', 'img:data-src'] } }] }, { //字体文件处理 test: /\.(ttf|woff|woff2|eot|svg)$/, use: [{ loader: 'file-loader', options: { outputPath: 'fonts/' } }] } ], } plugins: [ new HtmlWebpackPlugin({ template: "./public/index.html",//模板文件位置 filename: "webpack.html"//打包后的文件名 minify: { minimize: true,是否打包为最小值 removeAttributeQuotes: true,//去除引号 removeComments: true,//去除注释 collapseWhitespace: true,//去除空格 minifyCSS: true,//压缩html内的样式 minifyJS: true,//压缩html内的js removeEmptyElements: true, //清楚内容为空的元素 }, hash: true,//引入产出资源时加上哈希避免缓存 }), ] }
webpack.dev.conf.js 文件配置
const path = require('path') const webpack = require('webpack') const merge = require('webpack-merge') const require = require('./webpack.common.conf.js') module.exports = merge(common, { devtool: 'cheap-module-eval-source-map', devServer: { contentBase: './build',//设置服务器访问的基本目录 host: 'localhost',//服务器的ip地址 port: 8080,//端口 hot: true,//开启热模块替换 hotOnly: true, }, plugins: [ new CopyWebpackPlugin([ { from: __dirname + '/public/assets',//项目中静态资源的路径 to: __dirname + '/build/assets'//打包后静态资源拷贝到的路径 } ]), new webpack.NamedModulesPlugin(),//模块热替换功能 new webpack.HotModuleReplacementPlugin() ] })
webpack.prod.conf.js 文件配置
const path = require('path') const webpack = require('webpack') const ExtractTestPlugin = require('extract-test-webpack-plugin')//提取分离CSS const MiniCssExtractPlugin = require('mini-css-extract-plugin')//提取分离CSS const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')//压缩css及优化css结构 const CopyWebpackPlugin = require('copy-webpack-plugin')//拷贝静态文件 const CleanWebpackPlugin = require('clean-webpack-plugin')//用clean-webpack-plugin清除文件 const merge = require('webpack-merge') const require = require('./webpack.common.conf.js') module.exports = merge(common, { devtool: 'source-map', plugins: [ new CleanWebpackPlugin(['build'], { root: path.resolve(__dirname, '../') }),//需要写在前面 // new ExtractTestPlugin("./css/[name].css"), //打包后的文件路径及文件名,可以打包在一个文件内 new MiniCssExtractPlugin({ filename: "./css/[name].css" }), new OptimizeCssAssetsWebpackPlugin({ assetNameRegExp: /\.css$/g, cssProcessor: require("cssnano"), cssProcessorPluginOptions: { preset: ['default', { discardComments: { removeAll: true } }] }, canPrint: true }), new CopyWebpackPlugin([ { from: path.resolve(__dirname + '../public/assets'),//项目中静态资源的路径 to: path.resolve(__dirname + '/build/assets')//打包后静态资源拷贝到的路径 } ]) ] })
最后修修改package.json文件中的scripts
--congig可以指定所使用的配置文件
修改路径
第六章、优化打包速度
一、减少文件搜索范围
(1)优化resolve.extensions配置
在导入语句没有带文件后缀时,webpack会自动带上后缀去尝试询问文件是否存在。
-
- 在配置resolve.extensions需要注意:
- 后缀尝试列表尽可能小,
- 频率出现最高的文件后缀要最先放在最前面,
- 写导入语句时,尽可能带上后缀。
(2)优化resolve.modules配置
resolve.modules用于配置webpack去哪些目录下寻找第三方模块,resolve.modules的默认值是['resolve.modules'],会采用向上递归的方式查找。
(3)优化resolve.alias配置
(4)缩小文件匹配范围
include:需要处理的文件位置
exclude:排除掉不需要处理的文件位置
二、设置noParse
防止webpack解析哪些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有import、require、define的调用,或任何其他导入机制,忽略大型library可以提交构建性能,比如jquery、elementUI等库。
三、给bable-loader设置缓存
bable-loader提供了cacheDirectory特定选项(默认false):设置时,给定的目录会缓存加载器的结果。
四、使用happyPack
HappyPack基本原理:在webpack构建过程中,我们需要使用loader对js、css,图片,字体文件做转换操作,并且转换的文件的数量也是非常大的,且这些转换操作不能并发处理文件,而是需要一个个文件进行处理,HappyPack基本原理是将这部分任务分解到多个子进程中去并行处理,子进程处理完后把结果返回到主进程中,从而减少总的构建时间。
(1)安装
npm install happypcak --save-dev
(2)配置webpack.config.js文件
var HappyPack = require('happypack'); var happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }); // 省略其余配置 module: { loaders: [ { test: /\.less$/, loader: ExtractTextPlugin.extract( 'style', path.resolve(__dirname, './node_modules', 'happypack/loader') + '?id=less' ) } ] }, plugins: [ new HappyPack({ id: 'less', loaders: ['css!less'], threadPool: happyThreadPool, cache: true, verbose: true }) ]