1.打包后如何调试
我们使用了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和cheap-module-source-map会生成新的map文件, source-map会映射行和列,cheap-module-source-map只会映射行不会映射列
eval-source-map和cheap-module-eval-source-map不会生成新的map文件,而是在打包的js文件中, eval-source-map会映射行和列,cheap-module-eval-source-map只映射行不映射列
上面的4种打包速度是从上到下依次加快的。不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对执行和调试有一定的影响。
个人意见是 :
如果大型项目可以使用source-map,如果是中小型项目使用cheap-module-eval-source-map就完全可以应对
需要强调说明的是 :
source map只适用于开发阶段,上线前记得修改这些调试设置。
简单的配置: webpack.config.js
module.exports = {
//使用测试工具 eval-source-map
devtool: 'eval-source-map',
entry: __dirname + "/app/main.js",
output: {
path: __dirname + "/public",
filename: "bundle.js"
}
}
2.开发与生产环境的设置
一个项目中是有开发环境和生产环境的,这两个环境的依赖也是不同的。
-
开发依赖:
只在开发中用来帮助你进行开发,简化代码或者生成兼容设置的以来包。你可以打开package.json来查看,devDependencies的下面的这些包为开发使用的包。这些包在生产环境中并没有用处。 -
生产依赖:
就是比如我们的js使用了jquery,jquery的程序要在浏览器端起作用,也就是说我们最终的程序也需要这个包,这就是生产依赖。这些包在dependencies中。
2.1安装方法
我们以安装jquery为例
2.1.1 无法配置到package.json中
npm install jquery
安装完成后,你会发现在package.json中并不存在这个包的依赖。如果你项目拷贝给别人继续开发,或者别人和你git合作,再次下载项目npm install时就会缺少这个jquery包。项目就会无法正常运行,所以这也是我们最不赞成的安装方法
2.1.2 配置到package.json的开发环境
npm install jquery --save-dev
安装完成后,它存在于package.json的devDependencies中,也就是说它是开发环境中需要的,上线并不需要这个包的依赖。
2.1.3. 配置到package.json的生产环境
npm install jquery --save
安装完成后,它存在于package.json的dependencies中,也就是说它是生产环境需要依赖的包(上线时需要的以来包)。
安装全部依赖包
npm install
安装生产环境依赖包
npm install --production
2.2 配置开发和生产并行
package.json
window下:
"scripts": {
"dev":"set type=dev&webapck",
"build": "set type=build&webpack"
},
mac下:
"scripts": {
"dev":"export type=dev&&webpack",
"build": "export type=build&&webpack"
},
webpack.config.js
可以利用node的语法来读取type的值,然后根据type的值用if–else判断。
if(process.env.type== "build"){
var website={
publicPath:"http://192.168.0.104:1717/"
}
}else{
var website={
publicPath:"http://cdn.jspang.com/"
}
}
这样一来就可以根据type只给静态文件配置不同的路径了
执行开发环境
npm run dev
生产环境
npm run build
3.优雅打包第三方类库
引用第三方的框架是必不可少的,比如引入JQuery或者Vue.
我们任然以jquery为例
##安装 :
npm install --save jquery
安装时需要注意的时Jquery最终要在生产环境中使用,所以我们这里要使用–save进行安装。
##修改entry.js :
我们的目录是这样的:
entry.js是我们的入口js文件,我们在entry.js中引用jquery
//不写引入文件的路径时,会自动去node_module文件夹中找
import $ from "jquery";
$('#hcd').html('this is jquery');
打包后发现已经生效了。
用plugin引入 :
ProvidePlugin是一个webpack自带的插件,Provide的意思就是装备、提供。因为ProvidePlugin是webpack自带的插件,所以要先再webpack.config.js中引入webpack。
const webpack = require('webpack');
在webpack.config.js里引入必须使用require,否则会报错的。
引入成功后配置我们的plugins模块,代码如下。
plugins:[
new webpack.ProvidePlugin({
$:"jquery"
})
]
这是一种全局引用。别的文件就不再需要引用了
区别
- import引入方法:
引用后不管你在代码中使用不适用该类库,都会把该类库打包起来,这样有时就会让代码产生冗余。
- ProvidePlugin引入方法:
引用后只有在类库使用时,才按需进行打包,所以建议在工作使用插件的方式进行引入。
4.webpack的模块化引用
js中的模块化
新建hcd.js
function hcd(){
alert('this is hcd');
}
module.exports=hcd;
再在别的js文件中引入
import hcd from './hcd.js';
hcd();
webpack模块
其实和js的模块化是一样的。
我们将入口文件模块化,写在新建的entry_webpack.js
const entry = {};
entry.path = {
entry: __dirname + '/../src/entry.js'
};
module.exports = entry;
webpack.config.js
5.watch的正确使用
在初级开发阶段,使用webpack-dev-server就可以充当服务器和完成打包任务(在我前面的文章中有),但时随着你项目的进一步完成,可能需要前后台联调或者两个前端合并代码时,就需要一个公共的服务器了。这时候我们每次保存后手动打包显然效率太低,我们希望的场景是代码发生变化后,只要保存,webpack自动为我们进行打包。这个工具就是watch,这节课我们把wacht完全学会,你会发现在开发中更加的得心应手。
我在以前的博客中提到过直接在pakeage.json中配置–watch也是可以的,但那是初级用法,它是可以配置参数的。
在webpack.config.js中
具体代码:
watchOptions:{
//检测修改的时间,以毫秒为单位
poll:1000,
//防止重复保存而发生重复编译错误。这里设置的500是半秒内重复保存,不进行打包操作
aggregateTimeout:500,
//不监听的目录
ignored:/node_modules/,
}
使用自动打包命令
webpack --watch
#6.在打包的js中加入注释
使用的是webpack自带的BannerPlugin插件
首先引用webpack
const webpack = require('webapck');
在插中使用
plugins: [
new webpack.BannerPlugin('hcd版权所有'),
]
打包后的js
7.webpack优化黑技能
将引入的类库抽离出来,也就是说打包代码后,不会将代码打包到js文件中,而是分离出来
例如抽离jquery,vue(前提是你已经install过了)
第一步:修改入口文件
entry:{
entry:'./src/entry.js',
jQuery:'jquery',
vue:'vue'
},
第二步:引入插件
我们需要引入optimize优化插件,他是webpack自带的,
const webpack = rquire('webpack');
插件里边是需要配置的,具体配置项看下面的代码。
new webpack.optimize.CommonsChunkPlugin({
//name对应入口文件中的名字,我们起的是jQuery和vue
name:['jQuery','vue],
//把文件打包到哪里,是一个路径
filename:"assets/js/[name].js",
//最小打包的文件模块数,这里直接写2就好
minChunks:2
}),
- minChunks一般都是固定配置,但是不写是不行的,你会打包失败。
- filename是可以省略的,这是直接打包到了打包根目录下,我们这里直接打包到了dist文件夹下边。
配置完成后,我们可以先删掉以前打包的dist目录,然后用webpack再次打包,你会发现jquery和vue被抽离了出来,并且我们的entry.js文件变的很小。
8.静态资源集中输出
有时我们需要将本地的已经存在但在项目中***没有引用***的图片资源或者其他静态资源打包到服务器当中,这时我们就需要copy-webpack-plugin插件了
插件安装
npm install --save-dev copy-webpack-plugin
webpack.config.js中引入插件
const copyWebpackPlugin= require("copy-webpack-plugin");
配置插件
plugins: [
new copyWebpackPlugin([{
from:__dirname+'/src/public',
to:'./public'
}])
]
- from:
要打包的静态资源目录地址,这里的__dirname是指项目目录下,是node的一种语法,可以直接定位到本机的项目目录中。
- to:
要打包到的文件夹路径,跟随output配置中的目录。所以不需要再自己加__dirname。
9.热加载
我们需要使用webpack自带的HotModuleReplacementPlugin插件
API: http://www.css88.com/doc/webpack/plugins/hot-module-replacement-plugin/
在webpack.config.js
const webpack= require("webpack");
配置插件
new webpack.HotModuleReplacementPlugin({
// Options...
})
这个热加载和devServer自带的是不一样的,HotModuleReplacementPlugin可以实现像vue和react的局部刷新