基于 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 DOM模型操作
Dec 28 Javascript
DOM和XMLHttpRequest对象的属性和方法整理
Jan 04 Javascript
调试Javascript代码(浏览器F12及VS中debugger关键字)
Jan 25 Javascript
Javascript实现飞动广告效果的方法
May 25 Javascript
深入理解JavaScript中为什么string可以拥有方法
May 24 Javascript
Knockoutjs 学习系列(二)花式捆绑
Jun 07 Javascript
基于JS实现弹出一个隐藏的div窗口body页面变成灰色并且不可被编辑
Dec 14 Javascript
浅谈$_FILES数组为空的原因
Feb 16 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
May 17 Javascript
详解Vue中localstorage和sessionstorage的使用
Dec 22 Javascript
vue前后分离调起微信支付
Jul 29 Javascript
Element Breadcrumb 面包屑的使用方法
Jul 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
Gambit vs ForZe BO3 第三场 2.13
2021/03/10 DOTA
你需要知道的JavsScript可以做什么?
2007/06/29 Javascript
jquery控制左右箭头滚动图片列表的实例
2013/05/20 Javascript
js 将json字符串转换为json对象的方法解析
2013/11/13 Javascript
非常漂亮的JS+CSS图片幻灯切换特效
2013/11/20 Javascript
JavaScript获取页面中表单(form)数量的方法
2015/04/03 Javascript
JavaScript 模块的循环加载实现方法
2015/12/13 Javascript
jQuery包裹节点用法完整示例
2016/09/13 Javascript
微信小程序教程之本地图片上传(leancloud)实例详解
2016/11/16 Javascript
JavaScript结合HTML DOM实现联动菜单
2017/04/05 Javascript
Angular中$broadcast和$emit的使用方法详解
2017/05/22 Javascript
JavaScript的setter与getter方法
2017/11/29 Javascript
JS中Map和ForEach的区别
2018/02/05 Javascript
使用 node.js 模仿 Apache 小部分功能
2019/07/07 Javascript
在layui中使用form表单监听ajax异步验证注册的实例
2019/09/03 Javascript
利用React高阶组件实现一个面包屑导航的示例
2020/08/23 Javascript
[43:03]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
python抓取网页中的图片示例
2014/02/28 Python
python实现探测socket和web服务示例
2014/03/28 Python
Python判断Abundant Number的方法
2015/06/15 Python
使用Python下载歌词并嵌入歌曲文件中的实现代码
2015/11/13 Python
Python插件virtualenv搭建虚拟环境
2017/11/20 Python
Python爬虫之pandas基本安装与使用方法示例
2018/08/08 Python
对python GUI实现完美进度条的示例详解
2018/12/13 Python
正确理解Python中if __name__ == '__main__'
2019/01/24 Python
python字符串Intern机制详解
2019/07/01 Python
django-filter和普通查询的例子
2019/08/12 Python
基于Python的微信机器人开发 微信登录和获取好友列表实现解析
2019/08/21 Python
Python数据可视化实现漏斗图过程图解
2020/07/20 Python
详解Canvas实用库Fabric.js使用手册
2019/01/07 HTML / CSS
阿迪达斯德国官方网站:adidas德国
2017/07/12 全球购物
如何减少垃圾回收让内存更加有效使用
2013/10/18 面试题
初中数学教学反思
2014/01/16 职场文书
物流创业计划书
2014/02/01 职场文书
文艺晚会策划方案
2014/06/11 职场文书
SQL语句多表联合查询的方法示例
2022/04/18 MySQL