plugins插件介绍:
plugins是用来拓展webpack功能的,这些功能会在整个构建过程中生效,执行相关任务,loaders和plugins常常被弄混,但是他们其实是完全不同的东西,loaders是对于某一类文件的处理,因为webpack只认识js文件,要打包其他文件就要用到loader,是在打包构建的过程中用来处理源文件的(jsx,scss,less)一次处理一个,plugins并不直接操作单个文件,它直接对整个构建过程起作用
使用方法:
要使用某个插件,需要通过npm安装,然后在webpack.config.js中的pluins模块中添加该插件的一个实例,(plugins是一个数组,new一个插件即可)
插件:
webpack.DefinePlugin----在打包阶段定义全集变量
webpack.HashedModuleldsPlugin----保持moudle.id稳定
webpack.NoEmitOnErrorsPlugin----屏蔽错误
webpack.ProvidePlugin--提供库
copy-webpack-plugin-可以帮助拷贝内容
案例:
在业务代码中获取全局变量:
webpack.config.js文件中 plugin模块
plugins:[
new webpack.DefinePlugin({
'process.env':env,
'name':'小李'
})
new webpack.ProvidePlugin({
"$":'jquery'
})
]
为什么业务打包要带hash?? hash和缓存有关,为了标识代码是否被更改
页面中使用:
webpack.ProvidePlugin中的jq:
helloworld.vue:
mounted(){
$.ajax({
})
}
优点就是不用在每个vue文件中再次引用$,可以帮助提供全局的插件,虽然可以在main.js中引入全局但是会污染vue,
copy-webpack-plugin-可以帮助拷贝内容
比如在在项目中引入了100张图片,而你只使用了20张,打包的时候剩余的80张是不会打包进dist文件夹的,如果想打包进入就可以使用这个插件
webpack.NoEmitOnErrorsPlugin----屏蔽错误
在开发阶段帮助屏蔽一些错误,比如在打包的时候发生报错现象,打包会立马停止,加上这个插件后,会先打包完毕,
webpack3和webpack4的不同:
webpack4理念:0配置打包
webpack3在webpack配置中是没有mode这个配置的,webpack3对代码压缩必须要在plugins中配置
plugins:[
new webpack.optimize
]
webpack4中打包压缩: 直接在webpack.config.js中的mode中配置:
module.exports={
mode:"production"
}
webpack打包优化:(解决打包速度慢的问题)
Dll优化(提前打包第三方模块)
webpack的打包时间是由-模块,操作决定的;
dll打包原理:
我们改代码的时候一般改的就是业务代码,往往不会去修改第三方模块,所以打包的时候能不能忽略第三方模块呢???只处理业务代码,这样打包就提高速度了,所以打包之前能不能先处理好第三方模块,在真正打包的时候就不要再去动第三方模块!!!这就是dll原理,提前处理第三方模块,真正打包的时候不去动第三方模块
dll实现:
新建一个webpack.dll.config.js
const webpack = require('webpack');
module.exports = {
entry:{
vendor:['jquery','loadsh']------这里只提前要处理的引入第三方模块
},
output:{
path:__dirname:"/dll",
filename:"[name].dll.js",
library:'[name]_library'
},
plugins:[
new webpack.DllPlugin({
path:__dirname+"/dll/[name]-manifest.json",
name:'[name]_library'
})
]
}
然后在webpack.config.js中去通知webpack已经提前打包好第三方模块了: 在webpack.config.js中:
plugins:[
new webpack.DllReferencePlugin({
manifest:require('./dll/vendor-manifest.json')
})
]
执行: 先执行 webpack --config webpack.dll.congif.js 再执行 webapcl
Happypack优化(把单线程打包改为多线程打包):
Happypack原理:
js是单线程的,node有开多线程能力,打包是在node环境下进行的,webpack也是node写的(利用node能力开多个工作进程一起来打包,把单线程打包改为多线程打包)代替loader去打包
使用:
先安装下载 然后在webpack.config.js中
先在webpack.config.js中引入HappyPack;
const HappyPack = require('happyPack');
const os = require('os');//node内置模块-提供电脑的信息
const happyThreadPool = HappyPack.ThreadPool({size:os.cpus().length});//线程池-根据电脑cpu去确定
module.exports={
mode:"development",
entry:{
app:'./app.js'
},
output:{
filename:[name].js
},
module:{
rules:[
{
test:/\.js$/,
use:[
{
//loader:'babel-loader'
loader:'happypack/loader?id=happybabel'
}
]
},
{
test:/\.css$/,
use:'happypack/loader?id=happycss'
}
]
},
plugins:[
new HappyPack({
id:"happybabel",
loaders:['babel-loader?cacheDirectory=true'],
threadPool:happyThreadPool
}),
new HappyPack({
id:"happycss",
loaders:['css-loader?cacheDirectory=true'],
threadPool:happyThreadPool
}),
]
}
happypack不一定会加速,甚至会拖慢速度,不建议把所有的loader都用happypack替换 原因:打包快慢是由模块数量和操作决定的,也包括优化操作,一般不建议把css文件替换,一般.vue比较多
解决方案归纳:
- 如果是要对模块内容进行处理----Loader是第一解决方案
- 如果要增加一些特殊的功能--可以自定义增加插件
- 项目上的打包简化,可变性配置--通过编写相应的操作函数
骚操作1:
目的:把打包后的js文件中的bind全部替换为on,源文件不会改变
新建myloader.js
module.exports= function(context){
console.log(context);
return context.replace('bind','on');
}
在webpack.congif.js中
module.exports={
mode:"development",
entry:{
app:'./app.js'
},
output:{
filename:[name].js
},
module:{
rules:[
{
test:/\.js$/,
use:[
{
loader:'./myloader.js'
}
]
}
]
},
plugins:[
]
}
骚操作2:自定义plugin插件
目的: 把打包后的请求地址'./static/img/'替换为'www.xx.com'
新建文件夹myplugin; 再文件夹新建index.js
module.exports=a;
function a(){
}
a.prototype.apply=function(compiler){
//插件原理:所有插件都是基于一个生命周期的监听的
//emit,done等周期
//我在done周期上注册了一个插件changeStatic
//hooks获取webpack生命周期
compiler.hooks.done.tap('changeStatic',function(compilation){
//compilation打包结果
//compilation.toJson().assets为最终打包自愿的结果['./app.js','./index.html']
let context = compiler.options.context;//获取当前地址
let publicpath = path.resolve(context,'dist');//拿到dist目录
compilation.toJson().assets.forEach((ast)=>{
const filepath = path.resolve(publicpath,ast.name);
fs.readFile(filepath,function(err,file){
var newcontext = file.toString().replace('./static',www.xx.com);
fs.writeFile(filepath,newcontext);
})
})
});
}
在webpack.config.js中
先引入myplugin
const myplugin = require(./myplugin);
module.exports={
mode:"development",
entry:{
app:'./app.js'
},
output:{
filename:[name].js
},
module:{
rules:[
]
},
plugins:[
new myplugin(),
]
}