基于 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 相关文章推荐
B/S模式项目中常用的javascript汇总
Dec 17 Javascript
jQuery CSS()方法改变现有的CSS样式
Aug 20 Javascript
jQuery实现鼠标经过提示信息的地图热点效果
Apr 26 Javascript
JavaScrip调试技巧之断点调试
Oct 22 Javascript
理解JavaScript表单的基础知识
Jan 25 Javascript
Javascript复制实例详解
Jan 28 Javascript
JavaScript设计模式经典之工厂模式
Feb 24 Javascript
jquery实现页面常用的返回顶部效果
Mar 04 Javascript
Bootstrap组件学习之导航、标签、面包屑导航(精品)
May 17 Javascript
JavaScript中String对象的方法介绍
Jan 04 Javascript
JS实现数组去重,显示重复元素及个数的方法示例
Jan 21 Javascript
Vue 实现把表单form数据 转化成json格式的数据
Oct 29 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
php 从数据库提取二进制图片的处理代码
2009/09/09 PHP
php根据身份证号码计算年龄的实例代码
2014/01/18 PHP
php实现多城市切换特效
2015/08/09 PHP
jQuery 连续列表实现代码
2009/12/21 Javascript
Extjs学习笔记之八 继承和事件基础
2010/01/08 Javascript
基于jquery的9行js轻松实现tab控件示例
2013/10/12 Javascript
详解jquery uploadify 上传文件
2013/11/09 Javascript
js用闭包遍历树状数组的方法
2014/03/19 Javascript
JavaScript跨平台的开源框架NativeScript
2015/03/24 Javascript
jQuery实现布局高宽自适应的简单实例
2016/05/28 Javascript
xcode中获取js文件的路径方法(推荐)
2016/11/05 Javascript
详解angular2采用自定义指令(Directive)方式加载jquery插件
2017/02/09 Javascript
NodeJS收发GET和POST请求的示例代码
2017/08/25 NodeJs
vue使用v-for实现hover点击效果
2018/09/29 Javascript
基于vue-upload-component封装一个图片上传组件的示例
2018/10/16 Javascript
详解JavaScript中的函数、对象
2019/04/01 Javascript
js实现点赞效果
2020/03/16 Javascript
基于JavaScript获取url参数2种方法
2020/04/17 Javascript
Python格式化压缩后的JS文件的方法
2015/03/05 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
使用Python读取二进制文件的实例讲解
2018/07/09 Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
2020/01/18 Python
python绘制分布折线图的示例
2020/09/24 Python
详解CSS3中@media的实际使用
2015/08/04 HTML / CSS
CSS3实现王者匹配时的粒子动画效果
2019/04/12 HTML / CSS
使用HTML5做的导航条详细步骤
2020/10/19 HTML / CSS
德国高性价比网上药店:medpex
2017/07/09 全球购物
南京软件公司的.net程序员笔试题
2014/08/31 面试题
《卖木雕的少年》教学反思
2014/04/11 职场文书
2015年质检工作总结
2015/05/04 职场文书
2015年食品安全工作总结
2015/05/15 职场文书
贷款收入证明格式
2015/06/24 职场文书
民警忠诚教育心得体会
2016/01/23 职场文书
初一数学教学反思
2016/02/17 职场文书
详解MySQL数据库千万级数据查询和存储
2021/05/18 MySQL
Python实现byte转integer
2021/06/03 Python