前言
最近项目中在使用react/redux/koa做一个IM,打包工具自然选择了webpack
我主要使用了webpack 的下列功能
webpack 打包编译js文件
编译js文件支持多入口,版本控制,懒加载
js和样式文件都支持热替换,不需要每个简单的修改都要刷新等待
复杂的css sprites功能,支持sass 语法
支持sourcemap,无论在开发还是上线的时候都支持soucemap的功能
webpack的功能不止这些了,而且社区比较活跃,插件开发也挺容易的,真心不错的一个工具
下面是具体功能实现部分
---------- 我是华丽的分割线 ----------
js 编译相关
webpack最基础的功能就是编译js了,由于react最近比较火热,而且react项目大部分都是通过webpack 进行打包编译的,导致很多人认为webpack 只是适用于react项目,这是不对的,webpack适用于所有的前端项目
我的项目也在使用react和sass
entry: [
vendorCss: [
config.src.js + '/css/jquery.Jcrop.css'
],
app: [
config.src.js + '/main.jsx'],
vendors:vendors]
},
output: {
path: config.dest.js,
filename: '[name].[chunkhash].js'
},
module: {
loaders:[{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['babel-loader'] //babel必须放在第一位,不然sourcemap是编译后的代码
}, {
test: /\.(png|jpg|gif)$/, loader: 'file-loader'
},{
test: /\.scss/,
loader: 'style!css!postcss!sass?sourceMap'
}, {
test: /\.css/,
loader: 'style!css'
}
],
noParse: [
path.join(__dirname + '/client/node_modules/jquery/'),
path.join(__dirname + '/client/lib/**')
]
}
上面是一个简单的配置,页面的脚本分为两个vendor.js和app.js
上面的代码有一些潜在的坑:
output.filename 中[name].[chunkhash] 中的chunkhash 并不只是内容变得时候才更新,默认的跟机器名,时间戳都有关系,如果要只是生成文件内容的md5,可以使用
[webpack-md5-hash] ,也就是在plugins 里面添加 new WebpackMd5Hash()jsx的babel-loader必须放在第一位,如果需要jsx-loader,那么顺序就是
['babel-loader', 'jsx-loader'],否则生成的soucemap 代码是babel 编译后的es5 代码关于懒加载,除了多入口的方式,也可以在项目中使用require.ensure的方式,点击此处查看更多
-
支持soucemap的话可以配置devtool 为'#cheap-module-eval-source-map',devtool有很多种,常见的sourcemap有下面几个问题
1) sourcemap的代码是babel编译后的,这个主要是因为配置了devtool为eval,cheap-source-map 2) sourcemap 中文乱码了,这个主要是配置了含有eval的devtool, 比如cheap-module-eval-source-map 因此推荐开发的时候使用的sourcemap:cheap-module-source-map
更多可以点此此处 ,
上线后代码会经过uglifyJsPlugin进行压缩,下面是相关配置
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true,//这里的soucemap 不能少,可以在线上生成soucemap文件,便于调试
mangle: true
})
-
上线后的devtool要配置为source-map,有时候为了性能考虑,一定要配置这个插件
new webpack.DefinePlugin({
'process.env': { NODE_ENV: '"production"' }
})
可以在项目中配置一些alias,具体的可以查看此处,alias可以解决一些模块嵌套层级比较深,相对路径不好引用的bug
项目编译后生成的js 如果放到html页面里面呢?这里我自己写了一个插件,
使用gulp-template 进行文件替换。
export function buildViewHtml(dev) {
return function () {
this.plugin("done", function (stats) {
stats = stats.toJson();
let result = dev ? processDevHtml() : processProdHtml(stats.assetsByChunkName);//注意assetsByChunkName字段,包含chunkhash这些值
let sourceViewFile = path.join(__dirname, 'client', 'index.html');
let viewFile = path.join(__dirname, 'views');
gulp.src(sourceViewFile)
.pipe(template({
CSSHASH: result.cssHash ? JSON.stringify(result.cssHash) : null,
appJS: result.app,
vendorCss: result.vendorCss || null,
vendorsJS: result.vendors
}))
.pipe(gulp.dest(viewFile));
});
}
}
使用的时候在plugins里面配置上buildHtml(false)
下面的内容是hrm相关的,今天先写到这里,后续会补充更多
热替换 Hot Module Replacement
热替换(Hot Module Replacement),简称HMR,
是说应用可以动态的更新局部模块代码,而不需要刷新整个页面
这个在跨平台开发或者较复杂的项目中特别有用,比如我有个层级很深的操作,操作了10多次才进入这个界面,这个时候更改了一个小功能,如果没有热替换,只能刷新整个页面,再重复操作10多次才能看到效果,热替换改变了这一切
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。