基于 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 相关文章推荐
javascript取消文本选定的实现代码
Nov 14 Javascript
JS Replace()的高级使用方法介绍
Jun 29 Javascript
AngularJS执行流程详解
Feb 17 Javascript
js时间查询插件使用详解
Apr 07 Javascript
webpack配置文件和常用配置项介绍
Apr 28 Javascript
Bootstrap里的文件分别代表什么意思及其引用方法
May 01 Javascript
jQuery中将json数据显示到页面表格的方法
May 27 jQuery
JS返回页面时自动回滚到历史浏览位置
Sep 26 Javascript
React如何解决fetch跨域请求时session失效问题
Nov 02 Javascript
vue请求本地自己编写的json文件的方法
Apr 25 Javascript
使用Vue实现简单计算器
Feb 25 Javascript
详解前端任务构建利器Gulp.js使用指南
Apr 30 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
Symfony2学习笔记之插件格式分析
2016/03/17 PHP
php中青蛙跳台阶的问题解决方法
2018/10/14 PHP
Thinkphp5框架中引入Markdown编辑器操作示例
2020/06/03 PHP
JQuery从头学起第二讲
2010/07/04 Javascript
基于jquery的实现简单的表格中增加或删除下一行
2010/08/01 Javascript
javascript中的继承实例代码
2011/04/27 Javascript
很好用的js日历算法详细代码
2013/03/07 Javascript
基于IE下ul li 互相嵌套时的bug,排查,解决过程以及心得介绍
2013/05/07 Javascript
用html+css+js实现的一个简单的图片切换特效
2014/05/28 Javascript
js模拟淘宝网的多级选择菜单实现方法
2015/08/18 Javascript
基于jquery实现鼠标滚轮驱动的图片切换效果
2015/10/26 Javascript
jquery实现的V字形显示效果代码
2015/10/27 Javascript
js+css绘制颜色动态变化的圈中圈效果
2016/01/27 Javascript
JavaScript学习总结之JS、AJAX应用
2016/01/29 Javascript
JS实现的在线调色板实例(附demo源码下载)
2016/03/01 Javascript
AngularJS中指令的四种基本形式实例分析
2016/11/22 Javascript
Vue.js 2.0窥探之Virtual DOM到底是什么?
2017/02/10 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
JavaScript 中Date对象的格式化代码方法汇总
2017/09/06 Javascript
vue实现树形菜单效果
2018/03/19 Javascript
JavaScript基于对象方法实现数组去重及排序操作示例
2018/07/10 Javascript
Python更新数据库脚本两种方法及对比介绍
2017/07/27 Python
python 正确保留多位小数的实例
2018/07/16 Python
python求最大值,不使用内置函数的实现方法
2019/07/09 Python
django用户登录验证的完整示例代码
2019/07/21 Python
python文档字符串(函数使用说明)使用详解
2019/07/30 Python
浅谈keras 的抽象后端(from keras import backend as K)
2020/06/16 Python
一文带你了解Python 四种常见基础爬虫方法介绍
2020/12/04 Python
Expedia法国:全球最大在线旅游公司
2018/09/30 全球购物
物业管理专业个人的自我评价
2013/11/19 职场文书
小学清明节活动总结
2014/07/04 职场文书
求职意向书
2014/07/29 职场文书
社会实践活动总结格式
2015/05/11 职场文书
单位综合评价意见
2015/06/05 职场文书
「天才王子的赤字国家重生术」妮妮姆·拉雷粘土人开订
2022/03/21 日漫
JS setTimeout与setInterval的区别
2022/04/20 Javascript