基于 webpack2 实现的多入口项目脚手架详解


Posted in Javascript onJune 26, 2017

简介

基于 webpack2 实现的多入口项目脚手架,主要使用 extract-text-webpack-plugin 实现 js 、css 公共代码提取,html-webpack-plugin 实现 html 多入口,less-loader 实现 less 编译,postcss-loader 配置 autoprefixer 实现自动添加浏览器兼容前缀,html-withimg-loader 实现 html 内引入图片版本号添加和模板功能,babel-loader 实现 ES6 转码功能, happypack 多线程加速构建速度。

目录

├── dist   # 构建后的目录
├── config   # 项目配置文件
│ ├── webpack.config.js # webpack 配置文件
│ └── postcss.config.js # postcss 配置文件
├── src   # 程序源文件
│ └── js   # 入口
│ ├ └── index.js  # 匹配 view/index.html
│ ├ └── user  
│ ├ ├ ├── index.js # 匹配 view/user/index.html
│ ├ ├ ├── list.js # 匹配 view/user/list.html
│ ├ └── lib  # JS 库等,不参与路由匹配
│ ├ ├── jquery.js 
│ └── view   
│ ├ └── index.html # 对应 js/index.js
│ ├ └── user  
│ ├ ├── index.html # 对应 js/user/index.js
│ ├ ├── list.html # 对应 js/user/list.js
│ └── css   # css 文件目录
│ ├ └── base.css  
│ ├ └── iconfont.css 
│ └── font   # iconfont 文件目录
│ ├ └── iconfont.ttf  
│ ├ └── iconfont.css
│ └── img   # 图片文件目录
│ ├ └── pic1.jpg  
│ ├ └── pic2.png 
│ └── template  # html 模板目录
│ └── head.html  
│ └── foot.html

配置

多入口

根据 JS 目录获取多入口数组

const ROOT = process.cwd(); // 根目录

let entryJs = getEntry('./src/js/**/*.js');

/**
 * 根据目录获取入口
 * @param {[type]} globPath [description]
 * @return {[type]}  [description]
 */
function getEntry (globPath) {
 let entries = {};
 Glob.sync(globPath).forEach(function (entry) {
 let basename = path.basename(entry, path.extname(entry)),
 pathname = path.dirname(entry);
 // js/lib/*.js 不作为入口
 if (!entry.match(/\/js\/lib\//)) {
 entries[pathname.split('/').splice(3).join('/') + '/' + basename] = pathname + '/' + basename;
 }
 });
 return entries;
}

// webpack 配置
const config = {
 entry: entryJs,
 output: {
 filename: 'js/[name].js?[chunkhash:8]',
 chunkFilename: 'js/[name].js?[chunkhash:8]',
 path: path.resolve(ROOT, 'dist'),
 publicPath: '/'
 }, 
}

module

使用 babel 实现 ES2015 转 ES5,less 转 css 并使用 postcss 实现 autoprefixer 自动添加浏览器兼容,url-loader 实现 css 引用图片、字体添加版本号,html-withimg-loader 实现 html 引用图片添加版本号并实现模板功能。

module: {
 rules: [
 {
  test: /\.js$/,
  exclude: /(node_modules|bower_components)/,
  use: {
  loader: 'babel-loader?id=js',
  options: {
   presets: ['env']
  }
  }
 },
 {
  test: /\.(less|css)$/,
  use: ExtractTextPlugin.extract({
  fallback: 'style-loader?id=styles',
  use: [{
   loader: 'css-loader?id=styles',
   options: {
    minimize: !IsDev
   }
   }, 
   {
   loader: 'less-loader?id=styles'
   }, 
   {
   loader: 'postcss-loader?id=styles',
   options: {
    config: {
    path: PostcssConfigPath
    }
   }
   }
  ]
  })
 },
 {
  test: /\.(png|jpg|gif)$/,
  use: [
  {
   loader: 'url-loader',
   options: {
   limit: 100,
   publicPath: '',
   name: '/img/[name].[ext]?[hash:8]'
   }
  }
  ]
 },
 {
  test: /\.(eot|svg|ttf|woff)$/,
  use: [
  {
   loader: 'url-loader',
   options: {
   limit: 100,
   publicPath: '',
   name: '/font/[name].[ext]?[hash:8]'
   }
  }
  ]
 },
 // @see https://github.com/wzsxyz/html-withimg-loader
 {
  test: /\.(htm|html)$/i,
  loader: 'html-withimg-loader?min=false'
 }
 ]
},


// postcss.config.js
module.exports = {
 plugins: [
 require('autoprefixer')({
 browsers: ['> 1%', 'last 5 versions', 'not ie <= 9'],
 })
 ]
}

View 视图

根据目录对应关系,获取 js 对应的 html 入口

let entryHtml = getEntryHtml('./src/view/**/*.html'),
 configPlugins;

entryHtml.forEach(function (v) {
 configPlugins.push(new HtmlWebpackPlugin(v));
});

// webpack 配置
resolve: {
 alias: {
 views: path.resolve(ROOT, './src/view') 
 }
},

/**
 * 根据目录获取 Html 入口
 * @param {[type]} globPath [description]
 * @return {[type]}  [description]
 */
function getEntryHtml (globPath) {
 let entries = [];
 Glob.sync(globPath).forEach(function (entry) {
 let basename = path.basename(entry, path.extname(entry)),
 pathname = path.dirname(entry),
 // @see https://github.com/kangax/html-minifier#options-quick-reference
 minifyConfig = IsDev ? '' : {
 removeComments: true,
 collapseWhitespace: true,
 minifyCSS: true,
 minifyJS: true 
 };

 entries.push({
 filename: entry.split('/').splice(2).join('/'),
 template: entry,
 chunks: ['common', pathname.split('/').splice(3).join('/') + '/' + basename],
 minify: minifyConfig
 });

 });
 return entries;
}

plugins

使用 happypack 多线程加快构建速度,CommonsChunkPlugin 实现提取公用 js 为单独文件,extract-text-webpack-plugin 实现提取公用 css 为单独文件,

let configPlugins = [
 new HappyPack({
 id: 'js',
 // @see https://github.com/amireh/happypack
 threadPool: HappyThreadPool,
 loaders: ['babel-loader']
 }),
 new HappyPack({
 id: 'styles',
 threadPool: HappyThreadPool,
 loaders: ['style-loader', 'css-loader', 'less-loader', 'postcss-loader']
 }),
 new webpack.optimize.CommonsChunkPlugin({
 name: 'common'
 }),
 // @see https://github.com/webpack/webpack/tree/master/examples/multiple-entry-points-commons-chunk-css-bundle
 new ExtractTextPlugin({
 filename: 'css/[name].css?[contenthash:8]',
 allChunks: true
 })
];

entryHtml.forEach(function (v) {
 configPlugins.push(new HtmlWebpackPlugin(v));
});

// webpack 配置
plugins: configPlugins,

开发

webpack-dev-server 实现开发环境自动刷新等功能

// webpack 配置
devServer: {
 contentBase: [
 path.join(ROOT, 'src/')
 ],
 hot: false,
 host: '0.0.0.0',
 port: 8080
}

开发

npm start

http://localhost:8080/view

构建

cross-env 实现区分开发和生产环境构建

命令 说明

npm run dev 开发环境构建,不压缩代码

npm run build 生产环境构建,压缩代码

仓库:https://github.com/givebest/webpack2-multiple-entry

本地下载:http://xiazai.3water.com/201706/yuanma/webpack2-multiple-entry(3water.com).rar

总结

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

Javascript 相关文章推荐
js动态创建标签示例代码
Jun 09 Javascript
浅谈javascript属性onresize
Apr 20 Javascript
有关easyui-layout中的收缩层无法显示标题的解决办法
May 10 Javascript
浅谈Angularjs link和compile的使用区别
Oct 21 Javascript
arcgis for js 修改infowindow样式的方法
Nov 02 Javascript
jQuery EasyUI 页面加载等待及页面等待层
Feb 06 Javascript
node.js程序作为服务并在windows下开机自启动(用forever)
Mar 29 Javascript
通过webpack引入第三方库的方法
Jul 20 Javascript
vue.js 子组件无法获取父组件store值的解决方式
Nov 08 Javascript
IDEA配置jQuery, $符号不再显示黄色波浪线的问题
Oct 09 jQuery
jquery简易手风琴插件的封装
Oct 13 jQuery
vue render函数动态加载img的src路径操作
Oct 26 Javascript
JavaScript的六种继承方式(推荐)
Jun 26 #Javascript
JavaScript数据类型和变量_动力节点Java学院整理
Jun 26 #Javascript
JavaScript基本语法_动力节点Java学院整理
Jun 26 #Javascript
JavaScript条件判断_动力节点Java学院整理
Jun 26 #Javascript
JavaScript脚本语言是什么_动力节点Java学院整理
Jun 26 #Javascript
JavaScript简介_动力节点Java学院整理
Jun 26 #Javascript
JavaScript数组_动力节点Java学院整理
Jun 26 #Javascript
You might like
Thinkphp连表查询及数据导出方法示例
2016/10/15 PHP
PHP实现对文件锁进行加锁、解锁操作的方法
2017/07/04 PHP
文本框的字数限制功能jquery插件
2009/11/24 Javascript
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
jquery 获取dom固定元素 添加样式的简单实例
2014/02/04 Javascript
jquery实现全选和全不选功能效果的实现代码【推荐】
2016/05/05 Javascript
Augularjs-起步详解
2016/07/08 Javascript
JS匹配日期和时间的正则表达式示例
2017/05/12 Javascript
javascript中如何判断类型汇总
2019/05/14 Javascript
原生js实现的移动端可拖动进度条插件功能详解
2019/08/15 Javascript
小程序实现可拖动的悬浮按钮
2020/09/07 Javascript
[52:22]EG vs VG Supermajor小组赛B组 BO3 第一场 6.2
2018/06/03 DOTA
跟老齐学Python之集合的关系
2014/09/24 Python
python logging日志模块的详解
2017/10/29 Python
Python抓取框架Scrapy爬虫入门:页面提取
2017/12/01 Python
使用python3+xlrd解析Excel的实例
2018/05/04 Python
python检测主机的连通性并记录到文件的实例
2018/06/21 Python
Python2与Python3的区别实例总结
2019/04/17 Python
python 生成器和迭代器的原理解析
2019/10/12 Python
pymysql模块的操作实例
2019/12/17 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
浅谈numpy中np.array()与np.asarray的区别以及.tolist
2020/06/03 Python
Python实现爬取网页中动态加载的数据
2020/08/17 Python
Hotels.com中国区:好订网
2016/08/18 全球购物
意大利团购网站:Groupon意大利
2016/10/11 全球购物
实习销售业务员自我鉴定
2013/09/21 职场文书
语文教学随笔感言
2014/02/18 职场文书
媒矿安全生产承诺书
2014/05/23 职场文书
爱护公物标语
2014/06/24 职场文书
旅游局领导班子“四风”问题对照检查材料思想汇报
2014/09/29 职场文书
2014年幼儿园园务工作总结
2014/12/05 职场文书
2014年小学少先队工作总结
2014/12/18 职场文书
给老婆的检讨书1000字
2015/01/01 职场文书
Matlab如何实现矩阵复制扩充
2021/06/02 Python
Vue3.0中Ref与Reactive的区别示例详析
2021/07/07 Vue.js
MySQL Shell import_table数据导入的实现
2021/08/07 MySQL