webpack配置的最佳實(shí)踐分享
本文主要介紹了關(guān)于webpack配置的最佳實(shí)踐,本文分享的實(shí)踐具有以下的優(yōu)勢(shì):
- 使用happypack提升打包速度。
- 使用MD5 hash可以生成文件版本,進(jìn)行版本控制
- 在非單頁(yè)面的系統(tǒng)中支持多個(gè)入口的配置
- 模板中可以利用htmlplugin輸出一些配置性的信息
- 支持devserver,支持本地json數(shù)據(jù)的mock
一、webpack最佳實(shí)踐中的需求
1.熱加載
2.語(yǔ)法校驗(yàn)
3.js打包
4.模板打包
二、解決方案
1.webpack.config.json
var path = require('path'); var fs = require('fs'); var exec = require('child_process').exec; var HappyPack = require('happypack'); var merge = require('webpack-merge'); var webpack = require('webpack'); var WebpackMd5Hash = require('webpack-md5-hash'); var HtmlwebpackPlugin = require('html-webpack-plugin'); var ROOT_PATH = path.resolve(__dirname); var APP_PATH = path.resolve(ROOT_PATH, 'app'); var BUILD_PATH = path.resolve(ROOT_PATH, __dirname+'/devserver/public'); //取出頁(yè)面文件映射 function getHtmlPluginArr() { var data = JSON.parse(fs.readFileSync('entryconf.json', 'utf-8')); var pageList = data.pageList; var resultObj = { "pluginArr": [], "entryObj": {} }; for (var index = 0; index < pageList.length; index++) { var element = pageList[index]; var entry = element.entry; //通過(guò)對(duì)app.json中src的路徑截取獲得分發(fā)路徑 var filename = (function () { var filenameStr = entry.split("./app/page/")[1]; return filenameStr.substr(0, filenameStr.lastIndexOf(".")); })(); var title = element.title; var extra = element.extra; resultObj.entryObj[filename] = entry; //利用路徑一部分來(lái)進(jìn)行HtmlwebpackPlugin的chunks resultObj.pluginArr.push( new HtmlwebpackPlugin({ chunks: [filename], //當(dāng)前頁(yè)面js title: title, extra: extra,//包含頁(yè)面額外的配置信息 template: "app/" + "template.ejs", filename: 'views/'+filename + '.ejs', chunksSortMode: "dependency"http://按chunks的順序?qū)s進(jìn)行引入 }) ); //HappyPack, loader多進(jìn)程去處理文件 resultObj.pluginArr.push( new HappyPack({ id: 'html' }), new HappyPack({ id: 'css' }), new HappyPack({ id: 'js' }), new HappyPack({ id: 'tpl' }) ); } return resultObj; } var appJsonObj = getHtmlPluginArr(); /**通用配置 */ var commonConfig = { entry: appJsonObj.entryObj, module: { loaders: [ { test: /\.html$/, loader: "html?minimize=false", happy: {id: "html"} }, { test: /\.json$/, loader: "json" }, { test: /\.scss|\.css$/, loaders: ["style", "css", "sass"], happy: {id: "css"} }, { test: /\.(?:jpg|gif|png)$/, loader: 'url?limit=10240&name=images/[name]-[hash:10].[ext]' }, { test: /\.handlebars/, loader: "handlebars", query: { helperDirs: [APP_PATH + "/helper"] }, happy: {id: "tpl"} }, { test: /\.js$|\.jsx$/, exclude: /(node_modules|bower_components)/, loader: 'babel', query: { presets: ['es2015'] }, happy: {id: "js"} }, ] }, output: { path: BUILD_PATH, filename: "js/[name].js" }, externals: { "jquery": "jQuery" }, //配置短路徑引用 resolve: { extensions: ['', '.js', '.json', '.scss','.vue'], alias: { vue : 'vue/dist/vue.js' } }, plugins: appJsonObj.pluginArr, cache: true } module.exports = merge(commonConfig, { output: { publicPath: '/', path: BUILD_PATH, filename: "js/[name]-[chunkhash:10].js" }, plugins: [ new webpack.optimize.UglifyJsPlugin({ minimize: true }), new WebpackMd5Hash() ] });
2.模板文件的配置:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> <%= htmlWebpackPlugin.options.title || '上單'%> </title> </head> <body> <div id="main-container"></div> <% if (htmlWebpackPlugin.options.extra&&htmlWebpackPlugin.options.extra.js) {%> <% for(var i = 0;i < htmlWebpackPlugin.options.extra.js.length;i++){ %> <script src="<%= htmlWebpackPlugin.options.extra.js[i] %>"></script> <% } %> <% } %> </body> <script src="http://cdn.bootcss.com/jquery/2.2.3/jquery.min.js"></script> </html>
3.webpack.dev.config.json配置
var path = require('path'); var fs = require('fs'); var merge = require('webpack-merge'); var webpack = require('webpack'); var HtmlwebpackPlugin = require('html-webpack-plugin'); var OpenBrowserPlugin = require('open-browser-webpack-plugin'); var ROOT_PATH = path.resolve(__dirname); var APP_PATH = path.resolve(ROOT_PATH, 'app'); var BUILD_PATH = path.resolve(ROOT_PATH, 'build'); var MODULE_PATH = path.resolve(ROOT_PATH, 'node_modules'); //取出頁(yè)面文件映射 function getHtmlPluginArr() { var data = JSON.parse(fs.readFileSync('app/entries.json', 'utf-8')); var pageList = data.pageList; var resultObj = { "pluginArr": [], "entryObj": {} }; for (var index = 0; index < pageList.length; index++) { var element = pageList[index]; var src = element.entry; //通過(guò)對(duì)app.json中src的路徑截取獲得分發(fā)路徑 var dist = (function() { var s1 = src.split("./app/entries/")[1]; var s2 = s1.substr(0, s1.lastIndexOf("/")); return s2; })(); var title = element.title; var extra = element.extra; resultObj.entryObj[dist] = src; //利用路徑一部分來(lái)進(jìn)行HtmlwebpackPlugin的chunks resultObj.pluginArr.push( new HtmlwebpackPlugin({ chunks: [dist], //當(dāng)前頁(yè)面js title: title, extra: extra,//包含頁(yè)面額外的配置信息 template: "app/" + "template.ejs", filename: dist + '.html', chunksSortMode: "dependency" //按chunks的順序?qū)s進(jìn)行引入 }) ); } return resultObj; } var appJsonObj = getHtmlPluginArr(); /**通用配置 */ var commonConfig = { entry: appJsonObj.entryObj, module: { loaders: [ { test: /\.html$/, loader: "html?minimize=false" }, { test: /\.json$/, loader: "json" }, { test: /\.scss|\.css$/, loaders: ["style", "css", "sass"] }, { test: /\.(?:jpg|gif|png)$/, loader: 'url?limit=10240&name=../images/[name]-[hash:10].[ext]' }, { test: /\.handlebars/, loader: "handlebars" }, { test: /\.js$/, exclude: /(node_modules|bower_components)/, loader: 'babel', query: { presets: ['es2015','stage-3','react'] } }, { test: /\.jsx$/, exclude: /(node_modules|bower_components)/, loader: 'babel', query: { presets: ['react','stage-3','es2015']} } ] }, output: { path: BUILD_PATH, filename: "js/[name].js" }, externals: { "jquery": "jQuery" }, //配置短路徑引用 resolve: { alias: { module: path.resolve(APP_PATH, 'module'), service: path.resolve(APP_PATH, "services"), component: path.resolve(APP_PATH, "components"), entries: path.resolve(APP_PATH, "entries"), routes: path.resolve(APP_PATH, "routes"), node_modules: path.resolve(ROOT_PATH, 'node_modules') }, extensions: ['', '.js', '.jsx'] }, plugins: appJsonObj.pluginArr, devtool: "cheap-source-map", cache: true } //webpack-dev-server 提供的是內(nèi)存級(jí)別的server,不會(huì)生成build的文件夾 //訪問(wèn)路徑直接參照build下的路徑 如http://127.0.0.1:8080/shop/updateShop.html module.exports = merge(commonConfig, { devServer: { hot: true, inline: true, progress: true, host: process.env.HOST, port: "8808", proxy: { '/api/getLeftBar': { target: 'http://127.0.0.1:8808/mock',//dev secure: false }, '/api/getIndexData': { target: 'http://127.0.0.1:8808/mock',//dev secure: false }, '/api/getblogs': { target: 'http://127.0.0.1:8808/mock',//dev secure: false }, '/panda/*': { target: 'http://10.4.233.139:8411/',//dev secure: false }, //轉(zhuǎn)發(fā)至本地mock '/page3/*': { target: 'http://127.0.0.1:8808', secure: false } } }, plugins: [ new webpack.HotModuleReplacementPlugin(), new OpenBrowserPlugin({ url: 'http://127.0.0.1:8808/test.html' }) ] });
總結(jié)
以上就是關(guān)于webpack最佳配置的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
JS實(shí)現(xiàn)圓形進(jìn)度條拖拽滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)圓形進(jìn)度條拖拽滑動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10Javascript 中創(chuàng)建自定義對(duì)象的方法匯總
這篇文章主要匯總介紹了Javascript 中創(chuàng)建自定義對(duì)象的方法,需要的朋友可以參考下2014-12-12JavaScript代碼實(shí)現(xiàn)簡(jiǎn)單日歷效果
這篇文章主要為大家詳細(xì)介紹了JavaScript代碼實(shí)現(xiàn)簡(jiǎn)單日歷效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04json實(shí)現(xiàn)添加、遍歷與刪除屬性的方法
這篇文章主要介紹了json實(shí)現(xiàn)添加、遍歷與刪除屬性的方法,結(jié)合簡(jiǎn)單實(shí)例形式分析了json常見(jiàn)的添加、遍歷與刪除操作相關(guān)技巧,需要的朋友可以參考下2016-06-06微信小程序?qū)崿F(xiàn)點(diǎn)擊空白隱藏的方法示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)點(diǎn)擊空白隱藏的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08JS實(shí)現(xiàn)頁(yè)面指定區(qū)域全屏閱讀功能
這篇文章主要介紹了JS實(shí)現(xiàn)頁(yè)面指定區(qū)域全屏閱讀功能,實(shí)現(xiàn)流程大概是需要在項(xiàng)目中安裝vueuse及需要用到的頁(yè)面中引入useFullScreen,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06JavaScript數(shù)組方法的錯(cuò)誤使用例子
在本篇文章中我們給大家分享了幾種使用JavaScript數(shù)組容易出錯(cuò)的例子,需要的朋友們可以參考下。2018-09-09prototype.js簡(jiǎn)單實(shí)現(xiàn)ajax功能示例
這篇文章主要介紹了prototype.js簡(jiǎn)單實(shí)現(xiàn)ajax功能,結(jié)合實(shí)例形式分析了prototype.js前臺(tái)實(shí)現(xiàn)ajax與后臺(tái)struts的相關(guān)操作技巧,需要的朋友可以參考下2017-10-10