配置webpack打包react
1:安装npm install react react-dom -S
2:安装babel与react转换的插件 npm install @babel/preset-react
3:在.babelrc配置 "@bable/preset-react"
4:修改 test: /\.jsx?$/
tree Shaking
1:只支持静态引入的方式 import-->export defalut 动态引入require-->module.exports
2: --->export const a={} export const b={}
--->import {a}引入解构出a 虽然没有引入b 但打包时还是会将b模块打包
3:设置摇树模式
--->开发模式设置,不会帮助我们把没有引用的代码去掉生产模式,会自动帮助我们摇树,可以不用设置
webpack.config.js下 optimization:{usedExports:true}
package.json "sideEffects":
--->sideEffects:false对所有模块都进行tree shaking
--->但是当我们使用import './css/*.js' 或者import @babel/polyfill时 使用Tree Shaking打包时,发现此模块并没有import引入任何的模块
--->会认为我们并没有使用这个模块 就会不会进行打包 通过设置sideEffects:['@babel/polyfill','./css/*js']将这两个模块排除在外,不使用treeShaking进行打包
--->在development模式下,即使配置了,tree Shaking也没有真正的生效,它还是会保留没有引入的代码,方便查看报错代码的位置
--->在production模式下,tree-shaking才会真正的起作用
配置文件分割
1.npm install webpack-merge -D
2.merge(baseConfig,devConfig)
3.merge(baseConfig,proConfig)
配置文件 环境变量注入的方式
module.exports = (env)=>{
if(env && env.production){
return merge(baseConfig,proConfig)
}else{
return merge(baseConfig,devConfig)
}}、
package.json
"dev": "webpack-dev-server --config ./config/webpack.base.js",
"build": "webpack --env.production --config ./config/webpack.base.js"
codeSpliting
1.业务代码与第三方库 拆分很必要
--->体积大,加载时间长
--->业务逻辑变化,第三库不变,所以业务逻辑一变更,第三方库也要重新加载打包
optimization:{
//做代码分割
splitChunks:{
chunks:'all', //all 既支持异步也支持同步引入//async 异步引入第三方库 //initial 同步引入第三方库
minSize:30000,//最小尺寸 只有当模块大于30kb才会被分离出去
minChunks:x,//模块至少被引入了x次,才会被分割,默认值为1 第三方库只要被一个模块引入了就分割出去
name:true,//设置打包后的名称功能的开启
cacheGroups:{
other:{
chunks'initial',
test:/react|lodash/,//过滤,只检测react,lodash第三方库
name:'other',//打包后的名字,
minSize:30000,
minChunks:1
},
vendors:{
test:/[\\/]node_modules[\\/]/,//过滤,检测是否在/node_modules/目录下
name:'vendors',//打包后的名字,
priority:-10,//缓存组的优先级,数字越大,优先级越高,打包匹配的顺序
},
default:{
minChunks:2,
priority:-20
}}}}
2 分析打包的信息
2.1.script --profile --json >stats.json 自动生成stats.json文件
2.2.打开分析工具 http://webpack.github.io/analyse/ 或者 https://github.com/webpack-contrib webpack-bundle-analyzer
3 import(/* webpackPrefetch:true*/"./a.js") //预存取 当主进程都加载完毕后,网络得到空闲,就去加载异步引入的模块
该函数接受源代码 接受参数 options
resolveLoader:{
//查找loader时,先去node_modules下查找,查找不到时,再去loaders目录下
modules:["node_modules","./loaders"]
},
use:[
{ 'replaceLoader',
{
loader:'replaceLoaderAsync',
options:{
name:'kkb'
}
}
}
]
module.exports =function(source){
console.log(this.query) //query是一个对象={name:'kkb'}也就是options
const result source.replace('你好',this.query.name)
this.callback(err,result)// err是错误信息 Error|null,可以返回多个参数
//处理异步代码 this.async()返回的而是callback在异步代码中 返回时直接使用cb(null,result)
const cb = this.async()
}
设计模式 事件驱动 发布订阅 plugin 是一个类,构造函数接受一个 options 就是 new xxxplugin({})传过来的参数 里面包含一个 apply(compiler) compiler 包含很多 hooks
//作用 在dist目录产生之前,先产生一个txt文件
class CopyrightWebpackPlugin {
constructor(options) {
console.log(options);
}
//compiler是一个webpack实例 包含打包的所有信息
//compilation是本次打包的信息
apply(compiler) {
//emit 是在dist资源目录产生之前触发的钩子
compiler.hooks.emit.tapAsync(
"CopyrightWebpackPlugin",
(compilation, cb) => {
//compilation.assets包含即将放入dist文件下的资源
compilation.assets["copyright.txt"] = {
source: function() {
return "hello copy";
}, //.txt文件下的内容
size: function() {
return 1024;
} //.txt文件的体积
};
cb();
}
);
}
}
module.exports = CopyrightWebpackPlugin;
development 打包以后实际就是一个闭包函数----浏览器能运行的代码 function()(入口文件:function(){源代码})