webpack介绍
为什么要打包呢,因为你用react,vue写的浏览器不认识,ES6也不能被完全兼容,所以打包转成浏览器认识的代码。那打包完的代码还算MVVM嘛,那必须的。没有优化的打包,bundle文件就像是一桶水,优化后,桶装水就被分成了大小不一的瓶装压缩~~'农夫三拳'~~。
前后端分离,代码模块化,组件化开发的单页面应用。最后还是要打包成HTML加载js,css,图片等资源的形式 - 涉及到打包,SEO问题
单页面应用所有的都在一个页面完成 - 涉及到路由问题
webpack大概就是:找到入口文件,然后递归依赖模块,收集依赖,然后开始转换,比如通过babel将ES6转为AST(抽象语法树)再转为ES5。通过less-loder将less转为css。最后用eval运行生成bundle文件
"webpack": "^4.35.2",
webpack.config.js -> github.com/coldLemon/w…
run build结果如下,该图片为speed-mesure插件运行结果
下图为打包后的文件结构
打包完也就是我们所熟悉的HTML+CSS+JS基本形式 下面来介绍一下:webpack几个基本模块
-
entry(入口)
`` 可以是单个入口:字符串 也可以是多个入口:数组,对象(官方推荐) 多个入口主要用来打包区分第三方库与业务代码(webpack4+已不推荐),也可以打包成多页面。
entry: {
main: "./src/index.js",
//main也是打包输出后的文件名
},
-
output(打包输出)
output: {
path: path.join(__dirname, '/dist'),
//1.path:入磁盘路径 2.__dirname:当前文件同级目录
filename: "[name].[hash:8].js"
//[name]:占位符,本文与entry的main 对应
//[hash:8] 模块层面的hash,8代表8位
},
-
Module
{
test: /\.(css|less|sass)$/,
//正则匹配 ‘.’是以啥开头,$是以啥结尾 |就是或
use: [ //使用啥loader来解析匹配到的文件
MiniCssExtractPlugin.loader,
// 'style-loader', //官网tip: 该插件不能和style 一起用
'cache-loader', //loader缓存
'css-loader',
'less-loader'
],
// exclude: /node_modules/
//这里不明白node_modeles的less 也需要loader 来处理?
通过test正则匹配文件的后名,然后用相对用的loader处理
-
Resolve
resolve:{
extensions:['.js','.vue','.json'],
//文件若无结尾,会按数组顺序逐个为文件匹配。(文件可以不加扩展名)
alias:{//文件路径简写
Components : path.resolve(__dirname,'src/components/'),
Pages: path.resolve(__dirname,'src/pages/')
}
}
}
-
Plugins
plugin就是个构造函数吧。具体用法还是要见构造函数干啥用的
plugins: [
new HtmlWebpackPlugin({
title: 'gege',
template: path.resolve(__dirname,'index.html'),///指定要打包的html路径和文件名
filename: "index.html",//指定输出路径和文件名(相对js的路径)
hash: true,
minify: {
//压缩HTML
removeComments: true,
collapseWhitespace: true
}
})
,
new MiniCssExtractPlugin({
// filename:'[name]_[contenthash:8].css'
filename:'[name].css',
chunkFilename:'[id].css',
}),
new VueLoaderPlugin(),
new CleanWebpackPlugin(),
],
再优化
其实上面也边做优化了,下面再进一步的
-
按需加载
module.exports = {
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component", //安装babel-plugin-component 饿了吗->vue用
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
// [
// "import",{ //安装babel-plugin-import ant->antd用
// "libraryName":"element-ui",
// }
// ]
]
}
-
optimization(优化)
splitChunks: { //分割第三方库
chunks: "all", //async异步代码分割 initial同步代码分割 all同步异步分割都开启
minSize: 30000, //字节 引入的文件大于30kb才进行分割
//maxSize: 50000, //50kb,尝试将大于50kb的文件拆分成n个50kb的文件
minChunks: 1, //模块至少使用次数
maxAsyncRequests: 5, //同时加载的模块数量最多是5个,只分割出同时引入的前5个文件
maxInitialRequests: 3, //首页加载的时候引入的文件最多3个
automaticNameDelimiter: '~', //缓存组和生成文件名称之间的连接符
name: true, //缓存组里面的filename生效,覆盖默认命名
cacheGroups: { //缓存组,将所有加载模块放在缓存里面一起分割打包
vendors: { //自定义打包模块
test: /[\\/]node_modules[\\/]/,
priority: -10, //优先级,先打包到哪个组里面,值越大,优先级越高
filename: 'vendors.js',
},
default: { //默认打包模块
priority: -20,
reuseExistingChunk: true, //模块嵌套引入时,判断是否复用已经被打包的模块
filename: 'common.js'
}
}
}
-
DLLPlugin(单独打包)
大概就是将不怎么更新的包单独用webpack 打包(单独配置一个webpack.vender.config js文件),然后会生成manifest,相当于包依赖图。然后在html引入js 打包出的js 即可。这个和optmization.splitchunks单独打包成一个js类似吧。还有用externals引入第三方库,用CDN加载也一样吧。
const path=require('path')
const webpack =require('webpack')
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const dllBasePath = path.join(__dirname, 'dist','dll');
//只需要使用yarn dll一次就行
module.exports={
// mode:'production',
mode:'development',
entry:{
//把
vue:['vue','vue-router','vue-axios','vuex']
},
output:{
filename:'[name]_[hash].js',
//产出名字,(js引入的文件名,这里在HTML-webpack-plugin 对应)
path:dllBasePath, //js输出路径
library:'[name]_[fullhash]', //类库引入方式,import require and so on
libraryTarget: 'umd'
},
plugins:[
new webpack.DllPlugin({ //将此插件与output.library选项结合使用以公开(也称为全局作用域)dll函数
// context: __dirname,
//name:'[name]_[fullhash]',
manifest: require(path.resolve(__dirname, 'dist', 'manifest.json')),
//清单json文件的绝对路径(输出)
// entryOnly: true //仅公开入口点
}),
new CleanWebpackPlugin({ //这里要对象,数组会报错
// cleanOnceBeforeBuildPatterns: [path.resolve(__dirname,'dist/dll')]
}),//删除dll目录下的文件
]
}
yarn dll 后产不出manifest文件(路径问题),后来去react-cli看了下,它们的manifest都是在最外层的,还是两个,一个文件映射,一个是图片。然后我就改了manifest的输出路径到dist根目录下。
path:require(path.join(__dirname,'dist','manifest.json')),
现在打包后如下图所示:
打包速度是快了,但是打开dist文件中的css,发现未被压缩swiper等一些第三方组件也还没被压缩,被复用两次以上的element-ui还很大。
还有yarn start 后样式置空没了。低级错误:查询后是我将blank.css置空样式直接在index.html中导入,导致webpack从index.js入口中不能递归到css,在index.js中引入css即可
-
压缩css
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')//压缩css
引入后,在插件配置中new一个就完了。然后build之后可以看到css被压缩了
总结
基本打包后,需要优化。大概需要提取第三方组件库- 1.用externals,然后cdn引入
- 2.optimization.splitchunks分割代码
- 3.webpack.dllplugin单独打包
webpack独有的require.ensure(打包后会单独形成代码块,通过jsonp按需加载)实现路由懒加载。多线程打包,压缩js
本人小学毕业,所以这里只是基本配置,也参考(CV)了很多文章,学习用,如有错误请严格指出,本人临码涕零,thanks q U
~~现在学的好,五年后炒河粉没烦恼~~