webpack笔记
1、使用npm的默认配置初始化一个项目
nom init -y
2、安装并使用当前目录下的webpack,需要先卸载全局的webpack
npm uninstall webpack web pack-cli -g
3、将webpack安装在当前目录下,好处是不同工程适配不同版本的webpack
npm install webpack webpack-cli -D
4、安装任意版本的webpack(例:4.16.5版本)
先查看webpack的各种版本信息:npm info webpack
再安装:npm install webpack@4.16.5 web pack-cli -D
5、当前目录下的webpack命令需要加npx
npx webpack
6、 配置文件webpack.config.json基本格式
module.exports={
entry: ‘./index.js’, //入口文件路径
output: {
filename: ‘bundle.js’, //输出文件名
path: path.resolve(__direname, ‘bundle’) //输出文件的绝对路径
}
}
7、package.json中修改script字段可变更打包命令,例:npm run build
"scripts": {
"build": "webpack"
},
8、打包非js文件时需要使用loader,配置文件中增加module字段
module:{
rules:[{
test: /\.jpg|png|gif$/, //遇到jpg或png或gif格式的文件时
use: {
loader: ‘file-loader’, //使用file-loader
options: {
name: ‘[name].[ext]’, //file-loader配置文件名及后缀格式
}
}
}]
}
9、使用url-loader可以将文件转换成base64的url字符串,这样的好处是减少了一次http请求,
url-loader内嵌了file-loader,不需要重复安装file-loader
module:{
rules:[{
test: /\.jpg|png|gif$/, //遇到jpg或png或gif格式的文件时
use: {
loader: ‘url-loader’,
options: {
name: ‘[name].[ext]’, //file-loader配置文件名及后缀格式
outputPath: ‘images/’, //将这类生成的文件放在images文件夹下
limit: 204800 //小于200KB的文件使用url-loader,否则使用file-loader
}
}
}]
}
10、打包css、scss等样式文件时的配置
module:{
rules[{
test: /\.css|scss$/,
use:[
’style-loader’,
{
loader:’css-loader’,
options: {
importLoaders: 2, //遇到新的css引入,从下往上重新走一遍loader的解析
modules: true //使用css的模块模式,引入样式只在当前js文件有效,不影响子文件
}
},
‘sass-loader’,
‘postcss-loader’
]
}]
}
11、htmlWepackPlugin会在打包结束后自动生成html文件,并将打包生成的JS文件
自动引入这个html中,也可以手动配置html模版
const htmlWebpackPlugin = require(‘html-webpack-plugin’) //引入html打包插件
plugins:[
new htmlWebpackPlugin({template: ’src/index.html’}). //使用src目录下的index.html作为模版
]
12、cleanWebpackPlugin能够再打包前清理打包输出目录。
const CleanWebpackPlugin = require(‘clean-webpack-plugin’);
Plugins:[
new CleanWebpackPlugin(‘dist’) //dist为打包文件输出目录
]
13、source-map是源代码和打包代码的映射关系,cheap表示只精确到行且不映射loader等插件,module表示连同第三方插件和loader的映射也输出
eval表示通过sourceURL关联业务代码模块而不生成sourceMap文件,eval-source-map将生成的.map文件内容替换成嵌入sourceURL
devtool:’cheap-module-eval-source-map’ //开发环境最佳模式
14、加上—wathc命令后修改文件会自动打包(npm run webpack —watch),
但是这种方法只是将html页面当作静态界面访问,无法实现http请求或是ajax请求(产生跨域问题)
15、webpack-dev-server能够通过启动一个http服务器来完成代码变化时自动打包,同时更多的配置还能够
实现自动打开浏览器,无刷新修改页面等功能
启动服务器命令:npm run web pack-dev-server
webpack.config.js中的基础配置:
devServere:{
contentBase: ‘./build’ //打包文件生成目录
open: true //启动服务器时自动打开一个服务器
port: 8080 //启动端口为8080
}
16、webpack作为API在node中使用时,可以通过npm安装引入express服务器模块、webpack-dev-middleware打包模块
来自己实现一个带有自动打包功能的服务器(webpack-dev-server就是以上两个模块组合编写出来的)。
17、当修改文件后不想手动刷新页面时需要使用热模块更新插件
webpack.config.js配置:
const webpakc = require(“webpack”)
devServe:{
contentBase: ”./dist”,
hot: “true”, //开启热更新
hotOnly: true //热更新失效时是否自动刷新页面
},
plugins:[ new webpack.HotMoudleReplacementPlugin() ] //插件引入
18、ES6语法转ES5语法使用babel的webpack.config.js配置
module:{
rules: [
test: /\.js$/,
exclude: /node_modules/, //对该目录下的文件不做处理
loader: “babel-loader”,
options: {
presets:[ [“@babel/preset-env”,{
useBuiltIns: ‘usage’ //只对引用到的ES6语法做转化,设置此参数后不需要在文件中引入”@babel/polyfill”
}] ]
}
]
}
19、preset-env会污染全局变量,因此在写类库或组件库时最好代替使用plugin-transform-runtime,
它会将babel以闭包的的方式引入,不会污染全局变量。若babel的配置项过多,
则可以将配置写进文件名为.balbelrc的配置文件中
20、在导入模块时,tree shaking能够过滤掉模块中不被引用部分,而只导入引用部分。
它只识别和优化ESmodule方式(import)的静态引入,不支持优化CommonJS(require)方式的动态引入
tree shaking的webpack.config,js中的配置
optimization:{
usedExports: true //开启tree Shaking,便可只导入模块中被引用部分
}
在package.json中的配置:
“sideEffects”:[ “*.js”] //使tree Shaking不对此类文件做处理
20、webpack-merge插件能够将prod和dev中相同的打包配置参数抽出来,单独抽成一个公共的配置文件,在各自的配置文件中引入公共文件
然后在packge.json的scripts中设置打包命令,不同的打包命令分别对应开发环境和线上环境
21、code splitting代码分割——常用的公共模块文件在全局window中引入(通过html的src="url"引用而非js文件import),
使其分割成几个小文件,便于浏览器并行加载,同时公共模块改动少,分离后加载于浏览器内存中,便于复用。
22、webpack实现代码分割有两种方式:
①模块同步引入:只需要在webpack.config.json中配置
optimization:{
splitChunks:{
chunks: 'all'
}
}
②模块异步引入:件需要安装npm install --save-dev @babel/plugin-syntax-dynamic-import
并在.babelrc中使用该插:"plugins": ["@babel/plugin-syntax-dynamic-import"]
无需再加其他配置,webpack便会自动分割
https://www.cnblogs.com/jingouli/p/12255825.html
23、代码分割中webpack.config.js里的cacheGroups配置能够将满足同一条件的多个模块合并打包进一个文件
cacheGroups:{
venders:{
test:/[\\/]node_modules[\\/]/, //若模块路径包含此文件夹则写入同文件
priority: -10, //该venders组的优先级
filename: 'vendors.js' //打包后的文件名为vendors.js
}
}
24、模块懒加载——需要的时候通过事件触发进行加载。在vue等单页应用中,
所有页面组件的代码通过路由引入到一个文件里,而打包的时候则会通过webpack
的对这些模块页面进行代码分割,并通过访问url的方式进行异步懒加载
async function getComponent(){
const {default : _} = await import('lodash') //异步加载lodash模块
var element = document.createElement('div') //加载完成后执行后面的操作
element.innerHTML = _.join(['dell','lee'],'-')
return element
}
ducument.addEventListener('click',() =>{
getComponent.then(element => { //上一个then的返回值是下一个then的入参
document.body.appendChild(element)
})
})
25、打包分析——在打包命令中加入以下参数
webpack --profile --json > stats.json --config ./webpack.config.js
会在目录下生成一个stats.json文件。可以用webpack charts等打包分析工具分析该文件可以
获得一些模块依赖关系、模块是否重复打包、打包耗时等详情。
28、首屏渲染优化——将那些跟首屏无关的代码或文件抽出来,然后使用异步加载的方式在事件触发时
或是用户交互时再去加载这部分内容。F12使用coverage工具可以查看代码覆盖率(利用率)。
https://www.jianshu.com/p/2ad9535968aa
29、预加载——当异步加载的模块被抽出来后,我们可以在网络空闲时悄悄去预先加载这部分内容并存放在缓存中。
待用户需要时便可以直接从缓存中获取。通过使用webpack的prefetch和preload便可快速实现预加载的功能,
区别:prefetch会在核心模块完成后加载,preload会跟随核心模块一起加载
import(/* webpackPrefetch: true */ './lodash').then(({default: func}) => {
func()
})
30、chunkFilename是设置间接引用模块打包后的文件名字。
31、css文件代码分割——需要使用MiniCssExtractPlugin代替css-loader才能在打包后产生单独的css文件。
使用OptimizeCSSAssetsPlugin对css文件做代码压缩。css文件的打包可能会与tree shaking产生冲突——若css文件没被使用,
会被tree shaking过滤掉。因此可以在package.json中的sideEffects字段做配置
"sideEffects":[ "*.css" ]
32、webpack与浏览器缓存——为打包生成的文件名加上contentHash,当源码修改时,
打包生成的相应文件名hash也会发生变化,使用户可以自动重新加载新的文件。
output: {
filename: '[name].[contenthash].js', //使打包生成的文件名带上内容哈希值
chunkFilename: '[name].[contenthash].js' //使间接应用的模块打包生成的文件名带上内容哈希值
}
注:旧版本的webpack需要在optimization增加runtime参数
optimization:{
runtimeChunk: {
name:'runtime'
}
},
32、shimming——垫片。我们在引用jqueryUI等一些比较老的第三方模块时,这些模块中不会自动去
引入jquery,或者自己依赖的一些其他模块(曾经的jsp是手动按顺序引入到整个html中),即便我们在
自身模块中预先引入了jquery(与jsp按顺序加载js模块不同,被import引入的模块之间无法互相关联使用,
因为jsp的js文件this指向的是window,而在webpack模块化编程中this指向当前模块)。
这个时候就需要使用webpack的ProvidePlugin,并在webpack.config.js做以下配置
const webpack = require('webpack') //引入webpack
plugins[
new webpack.ProvidePlugin({
$: 'jquery' //当某模块中使用$时,webpack会在当前模块中自动引入jquery
})
]
32、更改当前模块this指向——安装imports-loader。当js文件需要经过多个loader处理时,要加一层use数组字段嵌套
use中的loader是按照从下往上的顺序处理的。
rules:[{
test: /\.js$/, //遇到js类型文件需按以下规则处理
exclude: /node_modules/, //对该目录下的文件不做处理
use:[
{loader: "babel-loader"}, //再用babel-loader做处理
{loader: "imports-loader?this=>window"} //由下往上,先用此loader做处理,使当前模块的this指向window
]
}]
33、库、插件打包:
module.exports={
entry: './index.js',
externals: ["lodash"], //打包忽略lodash模块,但插件被别人使用前,必须要先引入lodash(使用前需要配置垫片),避免了重复引用lodash
output: {
path : path.resolve(__dirname, 'dist'),
filename: 'mylibrary.js',
library: 'mylibrary', //导出的模块名为mylibrary
libraryTarget: 'this' //引入时,将mylibrary模块挂载到当前环境变量下,也可以是'window','umd'
}
}
注:可以在npm官网上注册一个账号,将打包生成的库上传上去,便可通过npm install 库名来安装使用
33、PWA——当服务器挂掉时,从浏览器缓存中读取资源并使页面任然正常加载。
const WorkboxPlugin = require('work-box-plugin'); //安装并引入pwa插件
plugins[
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true
})
]
33、typescripts的打包——使我们在敲代码的时候就提示错误。需要安装typescript和ts-loader(专门打包解析tsx格式的typescript文件),
还需要新建一个ts专用的配置文件——tsconfig.json
{
"compilerOptions": {
"module": "es6", //使用es6的模块引入方式(import)
"target": "es5", //打包语法时转换成es5的语法格式
"allowJs": true //允许在ts文件中引入js文件
}
}
在webpack.config.js中配置ts-loader
rules:[{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}],
若要提示第三方插件的使用报错,需要安装这个插件的ts版本,也就是这个插件的类型文件
例如npm install @types/lodash或npm install @types/vue
34、webpack请求转发代理如果是https时、需要加security参数配置
35 、webpack优化(1)、更新webpack、node、npm、babel、plugin版本
36、webpack优化(2)使尽可能少的的模块上经过loader处理,方法:使用include、exclude
37、webpack优化(3)resolved可配置不写后缀名、还可配置引入文件夹名时自动找到并引入其下的某个文件
38、webpack优化(4)使用dllplugin可以只在第一次时打包配置的第三方插件模块,之后的打包使用第一次的结果不再打包第三方插件
39、webpack优化(5)使用happypack等多线程node工具打包加速
39、webpack优化(6)使用tree shaking、code spliting等控制包的大小
40、webpack优化(7)借助打包分析工具分析打包情况