最近項目中在使用react/redux/koa作一個IM,打包工具天然選擇了webpackcss
我主要使用了webpack 的下列功能html
webpack 打包編譯js文件前端
編譯js文件支持多入口,版本控制,懶加載node
js和樣式文件都支持熱替換,不須要每一個簡單的修改都要刷新等待react
複雜的css sprites功能,支持sass 語法jquery
支持sourcemap,不管在開發仍是上線的時候都支持soucemap的功能webpack
webpack的功能不止這些了,並且社區比較活躍,插件開發也挺容易的,真心不錯的一個工具git
下面是具體功能實現部分github
---------- 我是華麗的分割線 ----------web
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),簡稱HMR,
是說應用能夠動態的更新局部模塊代碼,而不須要刷新整個頁面
這個在跨平臺開發或者較複雜的項目中特別有用,好比我有個層級很深的操做,操做了10屢次才進入這個界面,這個時候更改了一個小功能,若是沒有熱替換,只能刷新整個頁面,再重複操做10屢次才能看到效果,熱替換改變了這一切