webpack配置的最佳实践分享


Posted in Javascript onApril 21, 2017

本文主要介绍了关于webpack配置的最佳实践,本文分享的实践具有以下的优势:

  • 使用happypack提升打包速度。
  • 使用MD5 hash可以生成文件版本,进行版本控制
  • 在非单页面的系统中支持多个入口的配置
  • 模板中可以利用htmlplugin输出一些配置性的信息
  • 支持devserver,支持本地json数据的mock

一、webpack最佳实践中的需求

     1.热加载

     2.语法校验

     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');
//取出页面文件映射
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;
 //通过对app.json中src的路径截取获得分发路径
 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;
 //利用路径一部分来进行HtmlwebpackPlugin的chunks
 resultObj.pluginArr.push(
 new HtmlwebpackPlugin({
  chunks: [filename], //当前页面js
  title: title,
  extra: extra,//包含页面额外的配置信息
  template: "app/" + "template.ejs",
  filename: 'views/'+filename + '.ejs',
  chunksSortMode: "dependency"//按chunks的顺序对js进行引入
 })
 );
 //HappyPack, loader多进程去处理文件
 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="//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');
//取出页面文件映射
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;
 //通过对app.json中src的路径截取获得分发路径
 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;
 //利用路径一部分来进行HtmlwebpackPlugin的chunks
 resultObj.pluginArr.push(
 new HtmlwebpackPlugin({
 chunks: [dist], //当前页面js
 title: title,
 extra: extra,//包含页面额外的配置信息
 template: "app/" + "template.ejs",
 filename: dist + '.html',
 chunksSortMode: "dependency" //按chunks的顺序对js进行引入
 })
 );
 }
 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 提供的是内存级别的server,不会生成build的文件夹
//访问路径直接参照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
 },
 //转发至本地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'
 })
 ]
});

总结

以上就是关于webpack最佳配置的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery事件绑定和委托实例
Nov 25 Javascript
js使用心得分享
Jan 13 Javascript
jQuery禁用键盘后退屏蔽F5刷新及禁用右键单击
Jan 22 Javascript
jQuery和hwSlider实现内容响应式可触控滑动切换效果附源码下载(二)
Jun 22 Javascript
JavaScript面试开发常用的知识点总结
Aug 08 Javascript
详解angularJs模块ui-router之状态嵌套和视图嵌套
Apr 28 Javascript
在Vue.js中使用Mixins的方法
Sep 12 Javascript
Vue2.0结合webuploader实现文件分片上传功能
Mar 09 Javascript
支付宝小程序tabbar底部导航
Nov 06 Javascript
Vue实现剪贴板复制功能
Dec 31 Javascript
JS Thunk 函数的含义和用法实例总结
Apr 08 Javascript
js实现查询商品案例
Jul 22 Javascript
详解Vue.js 2.0 如何使用axios
Apr 21 #Javascript
ES6新特性四:变量的解构赋值实例
Apr 21 #Javascript
jQuery+pjax简单示例汇总
Apr 21 #jQuery
利用n工具轻松管理Node.js的版本
Apr 21 #Javascript
基于jQuery实现文字打印动态效果
Apr 21 #jQuery
ES6新特性三: Generator(生成器)函数详解
Apr 21 #Javascript
Cookies 和 Session的详解及区别
Apr 21 #Javascript
You might like
应用开发中涉及到的css和php笔记分享
2011/08/02 PHP
PHP数据对象PDO操作技巧小结
2016/09/27 PHP
php接口技术实例详解
2016/12/07 PHP
Laravel中的Blade模板引擎示例详解
2017/10/10 PHP
Mootools 1.2教程 选项卡效果(Tabs)
2009/09/15 Javascript
Jquery焦点图实例代码
2014/11/25 Javascript
js实现下拉列表选中某个值的方法(3种方法)
2015/12/17 Javascript
详解jQuery Mobile自定义标签
2016/01/06 Javascript
郁闷!ionic中获取ng-model绑定的值为undefined如何解决
2016/08/27 Javascript
详解打造 Vue.js 可复用组件
2017/03/24 Javascript
微信扫码支付零云插件版实例详解
2017/04/26 Javascript
基于 D3.js 绘制动态进度条的实例详解
2018/02/26 Javascript
vue 实现全选全不选的示例代码
2018/03/29 Javascript
使用vue.js在页面内组件监听scroll事件的方法
2018/09/11 Javascript
cdn模式下vue的基本用法详解
2018/10/07 Javascript
浅谈JavaScript 代码整洁之道
2018/10/23 Javascript
vue组件tabbar使用方法详解
2018/11/06 Javascript
Vue简单封装axios之解决post请求后端接收不到参数问题
2020/02/16 Javascript
在vue中实现清除echarts上次保留的数据(亲测有效)
2020/09/09 Javascript
vue图片裁剪插件vue-cropper使用方法详解
2020/12/16 Vue.js
[06:57]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD 选手采访
2021/03/11 DOTA
python解析xml文件操作实例
2014/10/05 Python
使用python为mysql实现restful接口
2018/01/05 Python
基于python的图片修复程序(实现水印去除)
2018/06/04 Python
PyTorch中Tensor的拼接与拆分的实现
2019/08/18 Python
在django-xadmin中APScheduler的启动初始化实例
2019/11/15 Python
使用HTML5里的classList操作CSS类
2016/06/28 HTML / CSS
土木工程专业个人求职信
2013/12/05 职场文书
巧克力蛋糕店创业计划书
2014/01/14 职场文书
计算机数据库专业职业生涯规划书
2014/02/08 职场文书
法律进社区实施方案
2014/03/21 职场文书
2014幼儿园家长工作总结
2014/11/10 职场文书
工作简历自我评价
2015/03/11 职场文书
刑事法律意见书
2015/06/04 职场文书
办公室管理规章制度
2015/08/04 职场文书
Java如何实现通过键盘输入一个数组
2022/02/15 Java/Android