前言
最近项目中在使用react/redux/koa做一个IM,打包工具自然选择了
我主要使用了webpack 的下列功能
webpack 打包编译js文件
编译js文件支持多入口,版本控制,懒加载
js和样式文件都支持热替换,不需要每个简单的修改都要刷新等待
复杂的css sprites功能,支持sass 语法
支持sourcemap,无论在开发还是上线的时候都支持soucemap的功能
webpack的功能不止这些了,而且社区比较活跃,插件开发也挺容易的,真心不错的一个工具
下面是具体功能实现部分
---------- 我是华丽的分割线 ----------
js 编译相关
webpack最基础的功能就是编译js了,由于react最近比较火热,而且react项目大部分都是通过webpack 进行打包编译的,导致很多人认为webpack 只是适用于react项目,这是不对的,webpack适用于所有的前端项目
我的项目也在使用react和sassentry: [ 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-map2) 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),简称,
是说应用可以动态的更新局部模块代码,而不需要刷新整个页面这个在跨平台开发或者较复杂的项目中特别有用,比如我有个层级很深的操作,操作了10多次才进入这个界面,这个时候更改了一个小功能,如果没有热替换,只能刷新整个页面,再重复操作10多次才能看到效果,热替换改变了这一切