地址:https://segmentfault.com/a/1190000006843916
地址:https://www.chungold.com/my/course/32
地址:http://jspang.com/2017/09/16/webpack3-2/
代码:https://github.com/zhaobao1830/webpack
一、认识webpack和安装
1、全局安装webpack npm install -g webpack(官网推荐在项目中独立安装)
2、做项目的时候,不能全局安装,会出问题,需要在项目里面新建package.json,通过这个安装wenpack,,npm install --save-dev webpack
备注:(1)全局安装webpack后,可以在cmd输入webpack -v查看版本号 (2)全局安装后,再项目中独立安装webpack的时候,不管package,json里webpack版本号是多少,都是全局安装的版本号 (3)没有全局安装webpack,在cmd输入webpack -v,会报webpack不是内部命令或外部命令
解决(3)的方案:
在package.json里面的scripts里面加 "build": "webpack这行代码就可以,在终端运行npm run build就相当于webpack,原理是npm run build就会去找node_modules下的webpack
npm run build src/entery.js dist/bundel.js相当于 webpack src/entery.js dist/bundel.js
1 "scripts": { 2 "test": "echo "Error: no test specified" && exit 1", 3 "build": "webpack" 4 },
在本地项目中安装webpack如何查看版本(不能用webpack -v):在node_modules里面找到webpack,打开package,json,找到"_id",它对应的就是webpack的版本
还有一个办法是:使用webpack打包项目,在打包时会显示webpack的版本号
3、webpack安装失败的解决办法:查看网络、查看node 版本、查看权限
4、webpack是干什么的? 打包(把多个js文件打包成一个js文件)、转换(把sass、stylus、less等不标准的css转换成标准的css,jade转换成标准的js)、优化(现在的项目用到的东西好多,可以用webpack进行优化)
二、让你快速上手一个demo
1、旧项目升级webpack有俩种方式:
删除node_modules,运行npm install ---save-dev webpack;(这个是只有在新项目中,没有其他依赖模块的情况下使用)
删除node_modules,在package.json里面,修改webpack的版本号,然后运行npm install(这是在老项目中,有很多依赖模块下使用)
2、使用webpack打包文件: cmd运行webpack 要打包的文件 打包后保存的文件
三、让你快速上手一个demo
1、配置文件webpack.config.js的基本结构
2、entry选项(入口配置)
3、output选项(出口配置)
4、多入口、多出口配置
webpack.config.js
1 const path=require('path'); 2 module.exports = { 3 // 入口 4 entry:{ 5 // 这个里面的entry和entry2是随便写的(多入口) 6 entry: './src/entry.js', 7 entry2:'./src/entry2.js' 8 }, 9 // 出口 10 output:{ 11 // 这是Node写法,表示的是绝对路劲 12 path:path.resolve(__dirname,'dist'), 13 // [name].js表示打包后的名字和打包前的一致(有几个入口文件,就打包成同名的几个出口文件) 14 // 这就是多出口 15 filename:'[name].js' 16 }, 17 // 模块,打包的时候,js转换、图片压缩都在这个里面配置 18 module:{}, 19 // 插件,需要的插件都在这里面配置 20 // 上面都是对象, 插件这个是数组,表示多个插件的意思 21 plugins:[], 22 // 配置开发时服务 23 devServer:{} 24 }
在src下新建entry.js和entry2.js
entry.js
1 document.getElementById("title").innerHTML = "testWebpack"
entry2.js
1 alert('tttt')
在根目录新建dist文件夹,创建Index.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <div id="title"></div> 9 <script src="entry.js"></script> 10 <script src="entry2.js"></script> 11 </body> 12 </html>
运行webpack,就会生成entry.js和entry2.js
四、服务和热更新
1、 webpack-config.js下的devServer
1 const path=require('path'); 2 module.exports = { 3 // 入口 4 entry:{ 5 // 这个里面的entry和entry2是随便写的(多入口) 6 entry: './src/entry.js', 7 entry2:'./src/entry2.js' 8 }, 9 // 出口 10 output:{ 11 // 这是Node写法,表示的是绝对路径 12 path:path.resolve(__dirname,'dist'), 13 // [name].js表示打包后的名字和打包前的一致(有几个入口文件,就打包成同名的几个出口文件) 14 // 这就是多出口 15 filename:'[name].js' 16 }, 17 // 模块,打包的时候,js转换、图片压缩都在这个里面配置 18 module:{}, 19 // 插件,需要的插件都在这里面配置 20 // 上面都是对象, 插件这个是数组,表示多个插件的意思 21 plugins:[], 22 // 配置开发时服务 23 devServer:{ 24 // 开发运行时监控的地方 25 contentBase:path.resolve(__dirname,'dist'), 26 // host不要填写localhost,因为系统、映射表被人修改后,会映射不到 27 // host: "本机IP地址" 28 host: "192.168.0.104", 29 // 是否启用服务器压缩 30 compress: true, 31 port: 1830, 32 proxy: { 33 '/api': { 34 target: 'http://localhost:3300', 35 pathRewrite: { '^/api': '' }, 36 changeOrigin: true, 37 secure: false // 接受 运行在 https 上的服务 38 } 39 } 40 } 41 }
上面devServer是配置一个服务器
2、安装 npm install webpack-dev-server --save-dev
3、package.json的配置
"scripts": {
"server": "webpack-dev-server" },
4、npm run server
把这个在浏览器打开
5、修改src下的js文件,页面内容会自动刷新(webpack3.6以上,自带热更新)
备注:只有新版本的webpack才可以这样。如果不能热更新,查看webpack版本
五、打包css文件
webpack在生产环境中有一个重要的作用就是减少http的请求数,就是把多个文件打包到一个JS里面,这样请求数量就可以减少好多。
Loaders
Loaders是Webpack最重要的功能之一,通过使用不同的loader,webpack可以对不同的文件格式进行处理
简单的举几个Loaders使用例子:
- 可以把SASS文件的写法转换成CSS,而不在使用其他转换工具。
- 可以把ES6或者ES7的代码,转换成大多浏览器兼容的JS代码。
- 可以把React中的JSX转换成JavaScript代码。
注意:所有的Loaders都需要在npm中单独进行安装,并在webpack.config.js里进行配置。下面我们对Loaders的配置型简单梳理一下。
- test:用于匹配处理文件的扩展名的表达式,这个选项是必须进行配置的;
- use:loader名称,就是你要使用模块的名称,这个选项也必须进行配置,否则报错;
- include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
- query:为loaders提供额外的设置选项(可选)。
打包css文件
创建一个index.css文件
body{ background-color: aqua; }
在entry.js里面引入index.css
// 路径一定要用相对路径,以防其他操作系统上不能用 import css from "./css/index.css"; document.getElementById("title").innerHTML = "hell zys";
解析css文件需要的俩个loader:style-loader(处理css里面的url路径问题)和css-loader(讲css插入到页面的style里)
先使用npm进行安装 npm install style-loader --save-dev和npm install css-loader --save-dev
安装好一会,就需要在webpack.base.js下进行配置
1 // 模块,打包的时候,js转换、图片压缩都在这个里面配置 2 module:{ 3 rules:[ 4 { 5 test:/.css$/, 6 (这出也可以使用use,我看现成的项目,这块都用的是Loader)loader: ['style-loader','css-loader']
或者是 use:[{loader:"style-loader"},{loader:"css-loader"}] 7 } 8 ] 9 },
loader的三种写法
第一种写法:直接用use
1 module:{ 2 rules:[ 3 { 4 test:/.css$/, 5 use:['style-loader','css-loader'] 6 } 7 ] 8 },
第二种写法:把use变成loader
1 module:{ 2 rules:[ 3 { 4 test:/.css$/, 5 loader:['style-loader','css-loader'] 6 } 7 ] 8 },
第三种写法:use+loader
1 module:{ 2 rules:[ 3 { 4 test:/.css$/, 5 use: [ 6 { 7 loader: "style-loader" 8 }, { 9 loader: "css-loader" 10 } 11 ] 12 } 13 ] 14 },
六、插件配置:配置JS压缩
js压缩需要在plugins里面进行配置,需要的插件是uglifyjs-webpack-plugin
webpack.config.js
1 const uglify = require('uglifyjs-webpack-plugin'); 2 3 plugins:[ 4 new uglify() 5 ],
备注:如果在终端执行webpack,js代码是可以正常压缩的;如果在终端执行npm run server,会报错
原因是devServer和js压缩发生冲突
解释:
开发环境中是基本不会对js进行压缩的,在开发预览时我们需要明确的报错行数和错误信息,所以完全没有必要压缩JavasScript代码。而生产环境中才会压缩JS代码,用于加快程序的工作效率。devServer用于开发环境,而压缩JS用于生产环境,在开发环境中作生产环境的事情所以Webpack设置了冲突报错。
在实际开发中,webpack配置文件是分开的,开发环境一个文件,生产环境一个文件。
七、插件配置:HTML文件的发布
配置webpack.config.js文件,先引入我们的html-webpack-plugin插件
const htmlPlugin= require('html-webpack-plugin');
引入后使用npm进行安装包:
npm install --save-dev html-webpack-plugin
最后在webpack.config.js里的plugins里进行插件配置,配置代码如下。
1 new htmlPlugin({ 2 minify:{ 3 removeAttributeQuotes:true 4 }, 5 hash:true, 6 template:'./src/index.html' 7 8 })
- minify:是对html文件进行压缩,removeAttrubuteQuotes是却掉属性的双引号。
- hash:为了开发中js有缓存效果,所以加入hash,这样可以有效避免缓存JS。
- template:是要打包的html模版路径和文件名称。
八、css中引入图片
代码:
css:
1 #tupian{ 2 background-image: url("../images/1.jpg"); 3 100px; 4 height: 100px; 5 }
index.html
1 <div id=tupian></div> 2 <div id=title></div>
webpack.config.js
1 rules:[ 2 { 3 test:/.css$/, 4 use: ["style-loader", "css-loader"] 5 }, 6 { 7 test:/.(png|jpg|gif)/ , 8 use:[{ 9 loader:'url-loader', 10 options:{ 11 limit:500000 12 } 13 }] 14 } 15 ]
- test:/.(png|jpg|gif)/是匹配图片文件后缀名称。
- use:是指定使用的loader和loader的配置参数。
- limit:是把小于500000B的文件打成Base64的格式,写入JS。
在css里引入图片,要打包成功,需要俩个Loader:url-loader和file-loader
npm install --save-dev url-loader file-loader
file-loader:解决引用路径的问题,拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。
url-loader:如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。
九、css分离和publicPath
在简单项目中,js代码会很少,css代码很多,这时打包的时候需要把css代码分离出来(webpack不支持这种行为)
可以使用extract-text-webpack-plugin
安装 npm install --save -dev extract-text-webpack-plugin
webpack.config.js引入
1 const extractTextPlugin = require("extract-text-webpack-plugin");
在plugins中配置
1 new extractTextPlugin("/css/index.css")
修改rules里面css部分
1 { 2 test: /.css$/, 3 use: extractTextPlugin.extract({ 4 fallback: "style-loader", 5 use: "css-loader" 6 }) 7 },
这样就可以运行webpack打包了
但是打包后有个问题,css路径不正确
解决办法:
publicPath:是在webpack.config.js文件的output选项中,主要作用就是处理静态文件路径的。
webpack.config.js 声明一个对象,叫website。
1 var website ={ 2 publicPath:"http://192.168.0.103:1717/" ip是本机的ip地址 端口号是devServer里配置的端口 3 }
修改output
1 output:{ 2 path:path.resolve(__dirname,'dist'), 3 filename:'[name].js', 4 publicPath:website.publicPath 5 },
运行webpack打包后,相对路径变成了绝对路径
十、html图片打包
示例:
在html页面引入ing 图片,打包后没有成功
<div><img src="images/2.jpg"></div>
解决办法:
npm install --save-dev html-withimg-loader
webpack.config.js
1 { 2 test: /.(htm|html)$/i, 3 use:[ 'html-withimg-loader'] 4 }
这样就可以打包了
十一、打包Less文件
先安装Less
npm install --save-dev less
安装less-loader
npm install --save-dev less-loader
loader配置webpack.config.js
1 { 2 test: /.less$/, 3 use: [{ 4 loader: "style-loader" // creates style nodes from JS strings 5 }, { 6 loader: "css-loader" // translates CSS into CommonJS 7 , { 8 loader: "less-loader" // compiles Less to CSS 9 }] 10 }
创建一个less文件
1 @base:#000; 2 #tLess{ 3 300px; 4 height:300px; 5 background-color:@base; 6 }
entry.js
1 // 路径一定要用相对路径,以防其他操作系统上不能用 2 import css from './css/index.css'; 3 import less from './css/black.less'; 4 document.getElementById("title").innerHTML = "hell zys";
这时就可以打包了(这时打包,less是在js里面)
如何把less打包的时候分离出来
webpack.config.js
1 { 2 test: /.less$/, 3 use: extractTextPlugin.extract({ 4 use: [{ 5 loader: "css-loader" 6 }, { 7 loader: "less-loader" 8 }], 9 // use style-loader in development 10 fallback: "style-loader" 11 }) 12 }
备注:如何在运行 npm run server的时候自动打开页面
在package.ison里面,scripts里的server里,最后面加一个--open
1 "server": "webpack-dev-server --open"
十三 、使用postcss自动给css加前缀
安装: postcss-loader和autoprefixer(自动添加前缀)
1 npm install --save-dev postcss-loader autoprefixer
在根目录下创建 postcss.config.js(用来配置postcss属性)
1 module.exports={ 2 plugins:[ 3 require('autoprefixer') 4 ] 5 }
webpack.config.js
css部分进行配置
1 { 2 test: /.css$/, 3 use: extractTextPlugin.extract({ 4 fallback: "style-loader", 5 use: [{loader:"css-loader",options:{importLoaders:1}},'postcss-loader'] //使用{}是为了可以加参数options
6 }) 7 },
例子:
1 #tupian{ 2 background-image: url("../images/1.jpg"); 3 100px; 4 height: 100px; 5 transform: rotate(7deg); 6 }
打包后
1 #tupian{ 2 background-image: url(http://192.168.0.102:1717/images/b3422d7fb5ba566d1cb9e81efb0e9d7e.jpg); 3 100px; 4 height: 100px; 5 -webkit-transform: rotate(7deg); 6 transform: rotate(7deg); 7 }
十四、使用purifycss-webpack消除未使用的css
我们在项目中会引入bootstrap框架,有些css不会用到;随着项目的复杂,有些css我们没有使用而且没有删除,打包的时候会把这些都打包进去
安装插件
npm i -D purifycss-webpack purify-css
在webpack.config.js里
因为我们需要同步检查html模板,所以我们需要引入node的glob对象使用,引入glob
const glob = require('glob');
引入purifycss-webpack
1 const PurifyCSSPlugin = require("purifycss-webpack");
plugins配置
1 new extractTextPlugin("css/index.css"), 2 new PurifyCSSPlugin({ 3 paths: glob.sync(path.join(__dirname, 'src/*.html')) 4 })
这里配置了一个paths,主要是需找html模板,purifycss根据这个配置会遍历你的文件,查找哪些css被使用了。
注意:这个插件一定要有extractTextPlugin配合
使用了上面的操作后,我们在打包的时候,就会把一些我们没有用到的css在打包中清除,减少打包后的大小
例子:
1 #tupian{ 2 background-image: url("../images/1.jpg"); 3 100px; 4 height: 100px; 5 transform: rotate(7deg); 6 } 7 .tt{ 8 color: #bbbbbb; 9 }
上面的tt没有使用
打包后:
1 #tLess { 2 300px; 3 height: 300px; 4 background-color: #000; 5 }
十五、使用babel编译es6、es7、es8
在前端开发中都开始使用ES6的语法了,虽然说webpack3增加了一些ES6的转换支持,但是实际效果不是很好,没发挥出真正的功能。所以在开发中还是喜欢添加Babel-loade
Babel是什么?
Babel其实是一个编译JavaScript的平台,它的强大之处表现在可以通过便宜帮你达到以下目的:
- 使用下一代的javaScript代码(ES6,ES7….),即使这些标准目前并未被当前的浏览器完全支持。
- 使用基于JavaScript进行了扩展的语言,比如React的JSX。
Babel的安装与配置
Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中,webpack可以把其不同的包整合在一起使用,对于每一个你需要的功能或拓展,你都需要安装单独的包(用得最多的是解析ES6的babel-preset-es2015包和解析JSX的babel-preset-react包)。
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
在webpack中配置Babel的方法如下:
1 { 2 test:/.(jsx|js)$/, 3 use:{ 4 loader:'babel-loader', 5 options:{ 6 presets:[ 7 "es2015","react" 8 ] 9 } 10 }, 11 exclude:/node_modules/ 12 }
测试:修改entry.js
1 import css from './css/index.css'; 2 { 3 let jspangString = 'Hello Webpack' 4 document.getElementById('title').innerHTML=jspangString; 5 }
上面的代码使用了ES6的let声明方法。如果你不使用Babel来进行转换,你会发现打包出来的js代码没有作兼容处理,使用了Babel转换的代码是进行处理过的。
.babelrc配置
虽然Babel可以直接在webpack.config.js中进行配置,但是考虑到babel具有非常多的配置选项,如果卸载webapck.config.js中会非常的雍长不可阅读,所以我们经常把配置卸载.babelrc文件里。
在项目根目录新建.babelrc文件,并把配置写到文件里。
.babelrc
{ "presets":["react","es2015"] }
.webpack.config.js里的loader配置
1 { 2 test:/.(jsx|js)$/, 3 use:{ 4 loader:'babel-loader', 5 }, 6 exclude:/node_modules/ 7 }
ENV:
现在网络上已经不流行babel-preset-es2015,现在官方推荐使用的是babel-preset-env,那我们为了紧跟潮流,我们在讲一下env的配置方法。
首先需要下载:
npm install --save-dev babel-preset-env
然后修改.babelrc里的配置文件。其实只要把之前的es2015换成env就可以了。
{ "presets": [“react”,"env"] }
总结:在实际工作中还是要安装Babel的,这样能更好的兼容每种浏览器,而把Babel的配置文件分解出来是最好的选择。
第16节:打包后如何调试
作为一个程序员每天的大部分工作就是调试自己写的程序,那我们使用了webpack后,所以代码都打包到了一起,给调试带来了麻烦,但是webpack已经为我们充分考虑好了这点,它支持生产Source Maps来方便我们的调试。
在使用webpack时只要通过简单的devtool配置,webapck就会自动给我们生产source maps 文件,map文件是一种对应编译文件和源文件的方法,让我们调试起来更简单。
四种选项
在配置devtool时,webpack给我们提供了四种选项。
- source-map:在一个单独文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度;
- cheap-module-source-map:在一个单独的文件中产生一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便。
- eval-source-map:使用eval打包源文件模块,在同一个文件中生产干净的完整版的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定要不开启这个选项。
- cheap-module-eval-source-map:这是在打包文件时最快的生产source map的方法,生产的 Source map 会和打包后的JavaScript文件同行显示,没有影射列,和eval-source-map选项具有相似的缺点。
四种打包模式,有上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对执行和调试有一定的影响。
个人意见是,如果大型项目可以使用source-map,如果是中小型项目使用eval-source-map就完全可以应对,需要强调说明的是,source map只适用于开发阶段,上线前记得修改这些调试设置。
简单的配置:
1 module.exports = { 2 devtool: 'eval-source-map', 3 entry: __dirname + "/app/main.js", 4 output: { 5 path: __dirname + "/public", 6 filename: "bundle.js" 7 } 8 } 9
总结:调试在开发中也是必不可少的,但是一定要记得在上线前一定要修改webpack配置,再打出上线包。
十七、开发环境和生产环境并行
修改package.json命令
其实就是添加一个dev设置,并通过环境变量来进行区分,下面是package.json里的值。
1 "scripts": { 2 "server": "webpack-dev-server --open", 3 "dev":"set type=dev&webapck", 4 "build": "set type=build&webpack" 5 },
修改webpack.config.js文件
可以利用node的语法来读取type的值,然后根据type的值用if–else判断。
1 if(process.env.type== "build"){ 2 var website={ 3 publicPath:"http://192.168.0.104:1717/" 4 } 5 }else{ 6 var website={ 7 publicPath:"http://cdn.jspang.com/" 8 } 9 }
如果想看传过来的是什么值,可以使用下面的代码
console.log( encodeURIComponent(process.env.type) );
Mac下的package.json设置
MAC电脑下需要把set换成export,并且要多加一个&符,具体代码如下。
1 "scripts": { 2 "server": "webpack-dev-server --open", 3 "dev":"export type=dev&&webpack", 4 "build": "export type=build&&webpack" 5 },
十八、webpack模块化配置
js中的模块化
创建一个zb.js
1 function zb() { 2 console.log('zb') 3 } 4 module.exports = zb
entry.js引入
1 import zb from 'zb.js' 2 3 zb()
webpack中的模块化
entry-webpack.js
1 //声明entry变量 2 const entry ={}; 3 //声明路径属性 4 entry.path={ 5 entry:'./src/entry.js' 6 } 7 //进行模块化 8 module.exports =entry;
webpack.config.js引入(注意:这里面引入不能用import,要用require)
const entry = require("./webpack_config/entry_webpack.js");
十九、引入第三方类库
npm install --save jquery
页面中引入:
import $ from 'jquery
全局引入:
ProvidePlugin是一个webpack自带的插件,Provide的意思就是装备、提供。因为ProvidePlugin是webpack自带的插件,所以要先再webpack.config.js中引入webpack。
const webpack = require('webpack');
引入成功后配置我们的plugins模块,代码如下:
1 plugins:[ 2 new webpack.ProvidePlugin({ 3 $:"jquery" 4 }) 5 ],
配置好后,就可以在你的入口文件中使用了,而不用再次引入了。这是一种全局的引入,在实际工作中也可以很好的规范项目所使用的第三方库。
二十、watch的正确用法(没有用过)
在初级开发阶段,使用webpack-dev-server就可以充当服务器和完成打包任务,但时随着你项目的进一步完成,可能需要前后台联调或者两个前端合并代码时,就需要一个公共的服务器了。这时候我们每次保存后手动打包显然效率太低,我们希望的场景是代码发生变化后,只要保存,webpack自动为我们进行打包。这个工具就是watch
watch的配置
webpack.config.js最下面
1 watchOptions:{ 2 //检测修改的时间,以毫秒为单位 3 poll:1000, 4 //防止重复保存而发生重复编译错误。这里设置的500是半秒内重复保存,不进行打包操作 5 aggregeateTimeout:500, 6 //不监听的目录 7 ignored:/node_modules/, 8 }
配置好后,我们就可以痛快的使用watch了,在大型项目中,这大大加快了我们的开发效率,不用反复的手动打包了。
BannerPlugin插件
工作中每个人写的代码都要写上备注,为的就是在发生问题时可以找到当时写代码的人。有时候也用于版权声明。
这个插件就是BannerPlugin,我们使用后会在JS中加上我们的版权或开发者声明。
new webpack.BannerPlugin('1830')
需要注意的是在使用这个插件之前必须引入webpack
const webpack = require('webpack');
这时在dist目录下的entery.js已经加上了版权声明。
二十一、webpack优化之抽离第三方组件库
在项目中,我们会引入多个第三方组件库(如:jquery),打包以后,会全部打包进入口文件,使得入口文件太大,这时候就需要把第三方组件剥离出来单独打包
ProvidePlugin和import
在第19节中学习了如何引入第三方类库,并引入了jquery,在引用JQuery时我们用了两种方法,第一种时import,第二种时使用ProvidePlugin插件。那两种引入方法有什么区别那?
- import引入方法:引用后不管你在代码中使用不适用该类库,都会把该类库打包起来,这样有时就会让代码产生冗余。
- ProvidePlugin引入方法:引用后只有在类库使用时,才按需进行打包,所以建议在工作使用插件的方式进行引入。
具体的对比操作,会在视频中演示,你会看出两种引入方法的对比打包结果。差距还是蛮大的。
抽离JQuery
上边的方法只是优化的第一步,工作中你会发现,不适用的类库几乎我们也不会引入,所以上边只是一个必要操作的第一步。那往往把第三方类库抽离出来,才是最好的解决方法。
第一步:修改入口文件
抽离的第一步是修改入口文件,把我们的JQuery也加入到入口文件中,看下面的代码。
webpack.config.js
1 entry:{ 2 entry:'./src/entry.js', 3 jquery:'jquery' 4 },
第二步:引入插件
我们需要引入optimize优化插件,插件里边是需要配置的,具体配置项看下面的代码。
1 new webpack.optimize.CommonsChunkPlugin({ 2 //name对应入口文件中的名字,我们起的是jQuery 3 name:'jquery', 4 //把文件打包到哪里,是一个路径 5 filename:"assets/js/jquery.min.js", 6 //最小打包的文件模块数,这里直接写2就好 7 minChunks:2 8 }),
minChunks一般都是固定配置,但是不写是不行的,你会打包失败。
filename是可以省略的,这是直接打包到了打包根目录下,我们这里直接打包到了dist文件夹下边。
配置完成后,我们可以先删掉以前打包的dist目录,然后用webpack再次打包,你会发现jquery被抽离了出来,并且我们的entry.js文件变的很小。
多个第三方类库抽离
会了如何抽离Jquery,但是在实际开发中,我们会引用不止一个第三方类库,这时也需要抽离。我们拿引入Vue为例,看看如何抽离出来。
第一步:我们先用npm 进行安装。
npm instawll vue --save
第二步:在入口配置中引入vue和jquery
1 entry:{ 2 entry:'./src/entry.js', 3 jquery:'jquery', 4 vue:'vue' 5 },
第三步:修改CommonsChunkPlugin配置
需要修改两个位置:
- 第一个是在name属性里把原来的字符串改为数组,因为我们要引入多个模块,所以是数组;
- 第二个是在filename属性中把我们输出的文件名改为匹配付[name],这项操作就是打包出来的名字跟随我们打包前的模块。
下面是我们修改的代码,你可以跟jquery抽离时对比一下。
1 new webpack.optimize.CommonsChunkPlugin({ 2 //name对应入口文件中的名字,我们起的是jQuery 3 name:['jquery','vue'], 4 //把文件打包到哪里,是一个路径 5 filename:"assets/js/[name].js", 6 //最小打包的文件模块数,这里直接写2就好 7 minChunks:2 8 }),
配置好后,我们就可以在控制台输入webpack进行打包了。你会看到我们预想的结果,jquery和vue都被我们抽离出来了。
总结:在项目开发中,我们很使用很多第三方类库,那好的做法就是把第三方这些类库全部抽离处理,这样在项目维护和性能上都是不错的选择。
二十二、静态资源打包输出
工作中会有一些已经存在但在项目中没有引用的图片资源或者其他静态资源(比如设计图、开发文档),这些静态资源有可能是文档,也有可能是一些额外的图片。项目组长会要求你打包时保留这些静态资源,直接打包到制定文件夹。其实打包这些资源只需要用到copy-webpack-plugin。
使用copy-webpack-plugin
copy-webpack-plugin就是专门为我们作静态资源转移的插件,不过它不同上两节使用的插件,它是需要安装的。
插件安装
npm install --save-dev copy-webpack-plugin
引入插件
安装好后,需要在webpack.config.js文件的头部引入这个插件才可以使用。
const copyWebpackPlugin= require("copy-webpack-plugin");
配置插件
引入之后我们就可以在plugins里边进行配置插件了
1 new copyWebpackPlugin([{ 2 from:__dirname+'/src/public', 3 to:'./public' 4 }])
- from:要打包的静态资源目录地址,这里的__dirname是指项目目录下,是node的一种语法,可以直接定位到本机的项目目录中。
- to:要打包到的文件夹路径,跟随output配置中的目录。所以不需要再自己加__dirname。
配置好后,我们就可以使用webpack 进行打包了,你会发现图片按照我们的配置打包了过去。
二十三、Json配置文件使用
在实际工作中,我们的项目都会配置一个Json的文件或者说API文件,作为项目的配置文件。有时候你也会从后台读取到一个json的文件,这节课就学习如何在webpack环境中使用Json。如果你会webpack1或者webpack2版本中,你是需要加载一个json-loader的loader进来的,但是在webpack3.x版本中,你不再需要另外引入了。
读出Json内容
第一步:现在我们的index.html模板中加入一个层,并给层一个Id,为了是在javascript代码中可以方便引用。
<div id="json"></div>
第二步:到src文件夹下,找到入口文件,我这里是entry.js文件。修改里边的代码,如下:
1 var json =require('../config.json'); 2 document.getElementById("json").innerHTML= json.name;
这两行代码非常简单,第一行是引入我们的json文件,第二行驶写入到到DOM中。
小技巧:
1、npm run dev以后自动打开浏览器,config里的index.js,dev里面的autoOpenBrowser设置为true