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 相关文章推荐
各浏览器对click方法的支持差异小结
Jul 31 Javascript
TimergliderJS 一个基于jQuery的时间轴插件
Dec 07 Javascript
Javascript判断图片尺寸大小实例分析
Jun 16 Javascript
最流行的Node.js精简型和全栈型开发框架介绍
Feb 26 Javascript
浅谈jQuery构造函数分析
May 11 Javascript
JS实现超简单的仿QQ折叠菜单效果
Sep 21 Javascript
node.js 和HTML5开发本地桌面应用程序
Dec 13 Javascript
JavaScript实现图片切换效果
Aug 12 Javascript
iview Upload组件多个文件上传的示例代码
Sep 30 Javascript
js针对图片加载失败的处理方法分析
Aug 24 Javascript
jquery实现直播弹幕效果
Nov 28 jQuery
JavaScript控制台的更多功能
Apr 28 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
php中current、next与reset函数用法实例
2014/11/17 PHP
php提取字符串中网站url地址的方法
2014/12/03 PHP
smarty模板引擎之内建函数用法
2015/03/30 PHP
jQuery 使用手册(五)
2009/09/23 Javascript
javascript 函数使用说明
2010/04/07 Javascript
表单切换,用回车键替换Tab健(不支持IE)
2011/07/20 Javascript
一个检测表单数据的JavaScript实例
2014/10/31 Javascript
jQuery对象的length属性用法实例
2014/12/27 Javascript
Ajax使用原生态JS验证用户名是否存在
2020/05/26 Javascript
jQuery Ajax实现跨域请求
2017/01/21 Javascript
AngularJS 最常用的八种功能(基础知识)
2017/06/26 Javascript
浅谈nodejs中的类定义和继承的套路
2017/07/26 NodeJs
angular2 ng2 @input和@output理解及示例
2017/10/10 Javascript
vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)
2018/08/24 Javascript
JS异步执行结果获取的3种解决方式
2019/02/19 Javascript
JavaScript数据结构与算法之二叉树实现查找最小值、最大值、给定值算法示例
2019/03/01 Javascript
利用JavaScript将Excel转换为JSON示例代码
2019/06/14 Javascript
Vue如何获取数据列表展示
2019/12/11 Javascript
javascript中innerHTML 获取或替换html内容的实现代码
2020/03/17 Javascript
Js生成随机数/随机字符串的方法小结【5种方法】
2020/05/27 Javascript
vue实践---根据不同环境,自动转换请求的url地址操作
2020/09/21 Javascript
JavaScript实现雪花飘落效果
2020/12/27 Javascript
初步讲解Python中的元组概念
2015/05/21 Python
Python调用C语言的方法【基于ctypes模块】
2018/01/22 Python
对python字典元素的添加与修改方法详解
2018/07/06 Python
Python基本数据结构之字典类型dict用法分析
2019/06/08 Python
Python使用import导入本地脚本及导入模块的技巧总结
2019/08/07 Python
Python2和3字符编码的区别知识点整理
2019/08/08 Python
python根据文本生成词云图代码实例
2019/11/15 Python
Python如何爬取b站热门视频并导入Excel
2020/08/10 Python
Expedia马来西亚旅游网站:廉价酒店,度假村和航班预订
2016/07/26 全球购物
党委领导班子整改方案
2014/09/30 职场文书
玄武湖导游词
2015/02/05 职场文书
朋友聚会祝酒词
2015/08/10 职场文书
学生会主席任命书
2015/09/21 职场文书
Appium中scroll和drag_and_drop根据元素位置滑动
2022/02/15 Python