详解webpack4多入口、多页面项目构建案例


Posted in Javascript onMay 25, 2018

趁工作之余从零构建了一个webpack4.x多页面应用程序。过程中也遇到一些坑,就记录下来了。

webpack核心概念

  1. Entry:入口,Webpack 执行构建的第一步将从 Entry 开始。
  2. Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
  3. Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
  4. Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
  5. Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
  6. Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
  7. 项目的运行主要围绕的就是这几大块

首先看一下构建后目录

├── build
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ ├── webpack.prod.conf.js
│ ├── webpack.rules.conf.js
├── src
│ ├── css
│ ├── js
│ ├── images
│ ├── assets
│ ├── pages
│ │ ├── index
│ │ │ ├── index.html
│ │ │ ├── index.js
│ │ │ └── index.scss
│ │ ├── login
│ │ │ ├── index.html
│ │ │ ├── index.js
│ │ │ └── index.scss

1.多页面的入口文件

修改 webpack.base.conf.js代码

entry: {
  // 多入口文件
  index: ['./src/pages/index/index.js',],
  login: './src/pages/login/index.js',
 },

2.配置开发服务器

npm install webpack-dev-server --save-dev
//修改 webpack.dev.conf.js代码

devServer: {
 contentBase: path.join(__dirname, "../dist"),
 publicPath:'/',
 host: "127.0.0.1",
 port: "8089",
 overlay: true, // 浏览器页面上显示错误
 // open: true, // 开启自动打开浏览器
 // stats: "errors-only", //stats: "errors-only"表示只打印错误:
 hot: true // 开启热更新
},
//修改package.json
scripts: {
 "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.dev.conf.js",
 "build": "cross-env NODE_ENV=production webpack --config build/webpack.prod.conf.js",
 "server": "live-server ./ --port=8888"
},

3.配置loader

{
 test: /\.(css|scss|sass)$/,
 // 不分离的写法
 // use: ["style-loader", "css-loader",sass-loader"]
 // 使用postcss不分离的写法
 // use: ["style-loader", "css-loader", sass-loader","postcss-loader"]
 // 此处为分离css的写法
 /*use: extractTextPlugin.extract({
  fallback: "style-loader",
  use: ["css-loader", "sass-loader"],
  // css中的基础路径
  publicPath: "../"
 })*/
 // 此处为使用postcss分离css的写法
 use: extractTextPlugin.extract({
  fallback: "style-loader",
  use: ["css-loader", "sass-loader", "postcss-loader"],
  // css中的基础路径
  publicPath: "../"

 })
},
{
 test: /\.js$/,
 use: ["babel-loader"],
 // 不检查node_modules下的js文件
 exclude: "/node_modules/"
}, {
 test: /\.(png|jpg|gif)$/,
 use: [{
  // 需要下载file-loader和url-loader
  loader: "url-loader",
  options: {
   limit: 5 * 1024,//小于这个时将会已base64位图片打包处理
   // 图片文件输出的文件夹
   outputPath: "images"
  }
 }]
}

4.从js中分离css

npm install extract-text-webpack-plugin --save-dev 
//这个插件在webpack4.x 运行时会有点问题,后面会提到
//修改 webpack.base.conf.js代码
// 分离css插件参数为提取出去的路径
new extractTextPlugin({
 filename: 'css/[name].[hash:8].min.css',
}),
5.处理css3属性前缀,消除冗余的css代码并压缩css

//属性自动加前缀
npm install postcss-loader --save-dev 
//在根目录新建postcss.config.js
module.exports = {
 plugins: [
  require('autoprefixer')//自动添加css前缀
 ]
};
//loader里加入postcss
{
 test: /\.(css|scss|sass)$/,
 // 此处为使用postcss分离css的写法
 use: extractTextPlugin.extract({
  fallback: "style-loader",
  use: ["css-loader", "sass-loader", "postcss-loader"],
  // css中的基础路径
  publicPath: "../"

 })
}
//修改package.json 加入css要兼容浏览器版本的代码
"browserslist": [
 "defaults",
 "not ie < 11",
 "last 2 versions",
 "> 1%",
 "iOS 7",
 "last 3 iOS versions"
]
//消除冗余css代码 使用glob模块去匹配文件所以还要安装glob模块
npm install purifycss-webpack --save-dev 
new purifyCssWebpack({
 paths: glob.sync(path.join(__dirname, "../src/pages/*/*.html"))
}),
//压缩css
npm install optimize-css-assets-webpack-plugin --save-dev 
//压缩css
//修改 webpack.prod.conf.js代码
new OptimizeCSSPlugin({
 cssProcessorOptions: {
  safe: true
 }
}),

5.清空打包目录

npm install clean-webpack-plugin --save-dev 
//修改 webpack.prod.conf.js代码
//删除dist目录
new cleanWebpackPlugin(['dist'], {
 root: path.resolve(__dirname, '../'), //根目录
 // verbose Write logs to console.
 verbose: true, //开启在控制台输出信息
 // dry Use boolean "true" to test/emulate delete. (will not remove files).
 // Default: false - remove files
 dry: false,
}),

6. 压缩js

npm install uglifyjs-webpack-plugin --save-dev 
//修改 webpack.prod.conf.js代码
//上线压缩 去除console等信息webpack4.x之后去除了webpack.optimize.UglifyJsPlugin
//https://github.com/mishoo/UglifyJS2/tree/harmony#compress-options
new UglifyJSPlugin({
 uglifyOptions: {
  compress: {
   warnings: false,
   drop_debugger: false,
   drop_console: true
  }
 }
}),

7.提取js公共模块

// webpack4里面移除了commonChunksPulgin插件,放在了config.optimization里面,提取js, vendor名字可改
optimization: {
 splitChunks: {
  cacheGroups: {
   vendor: {
    // test: /\.js$/,
    test: /[\\/]node_modules[\\/]/,
    chunks: "initial", //表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all;
    name: "vendor", //拆分出来块的名字(Chunk Names),默认由块名和hash值自动生成;
    enforce: true,
   }
  }
 }
},
//项目里配置了自动提取node_modules里用到的模块如jquery,也可以在原模板里面通过第三方cdn引入,又是另一种配置了。

在 webpack.base.conf.js利配置externals后webpack就不会去打包配置模块

externals: {
 'jquery': 'window.jQuery'
},
//externals就是webpack可以不处理应用的某些依赖库,使用externals配置后,依旧可以在代码中通过CMD、AMD或者window/global全局的方式访问。

8.复制静态资源

npm install copy-webpack-plugin --save-dev 
//静态资源输出,将src目录下的assets文件夹复制到dist目录下
new copyWebpackPlugin([{
 from: path.resolve(__dirname, "../src/assets"),
 to: './assets',
 ignore: ['.*']
}]),

9.产出html

npm install html-webpack-plugin --save-dev 
//修改webpack.base.conf.js代码
// 获取html-webpack-plugin参数的方法
var getHtmlConfig = function (name, chunks) {
 return {
  template: `./src/pages/${name}/index.html`,
  filename: `${name}.html`,
  // favicon: './favicon.ico',
  // title: title,
  inject: true,
  hash: true, //开启hash ?[hash]
  chunks: chunks,//页面要引入的包
  minify: process.env.NODE_ENV === "development" ? false : {
   removeComments: true, //移除HTML中的注释
   collapseWhitespace: true, //折叠空白区域 也就是压缩代码
   removeAttributeQuotes: true, //去除属性引用
  },
 };
};
//配置页面
const htmlArray = [{
  _html: 'index',
  title: '首页',
  chunks: ['vendor', 'index']//页面用到的vendor模块
 },
 {
  _html: 'login',
  title: '登录',
  chunks: ['login']
 },
];
//自动生成html模板
htmlArray.forEach((element) => {
 module.exports.plugins.push(new htmlWebpackPlugin(getHtmlConfig(element._html, element.chunks)));
})

10.性能优化 高大上的可视化分析模块

npm install webpack-bundle-analyzer --save-dev 
//修改 webpack.prod.conf.js代码
new BundleAnalyzerPlugin()
//npm run build 后会打开一个页面

详解webpack4多入口、多页面项目构建案例

cmd-markdown-logo

通过这个页面可以看到哪些页面是由哪些模块组成的,通过这个可视化页面可以更加方便去定位哪个包臃肿了,然后去优化。

报错 & 解决办法

Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead

后来发现webpack4不支持extract-text-webpack-plugin 必须下载next版本安装这个插件

npm install extract-text-webpack-plugin@next

https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/701

项目源码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Jquery数独游戏解析(一)-页面布局
Nov 05 Javascript
Jquery中使用setInterval和setTimeout的方法
Apr 08 Javascript
append和appendTo的区别以及appendChild用法
Dec 24 Javascript
详解Bootstrap插件
Apr 25 Javascript
全面解析Javascript无限添加QQ好友原理
Jun 15 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
Aug 24 Javascript
巧用weui.topTips验证数据的实例
Apr 17 Javascript
vue移动端实现下拉刷新
Apr 22 Javascript
Angular使用动态加载组件方法实现Dialog的示例
May 11 Javascript
js html实现计算器功能
Nov 13 Javascript
echarts多条折线图动态分层的实现方法
May 24 Javascript
详解ES6 CLASS在微信小程序中的应用实例
Apr 24 Javascript
js中的 || 与 &amp;&amp; 运算符详解
May 24 #Javascript
vue axios整合使用全攻略
May 24 #Javascript
vue路由拦截及页面跳转的设置方法
May 24 #Javascript
使用Vue自定义指令实现Select组件
May 24 #Javascript
详解Vue单元测试case写法
May 24 #Javascript
微信小程序通过保存图片分享到朋友圈功能
May 24 #Javascript
karma+webpack搭建vue单元测试环境的方法示例
May 24 #Javascript
You might like
PHP查询并删除数据库多列重复数据的方法(利用数组函数实现)
2016/02/23 PHP
JavaScript高级程序设计 错误处理与调试学习笔记
2011/09/10 Javascript
JavaScript 原型继承
2011/12/26 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
借助FileReader实现将文件编码为Base64后通过AJAX上传
2015/12/24 Javascript
JavaScript如何实现跨域请求
2016/08/05 Javascript
详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
2016/09/14 Javascript
Javascript中函数名.length属性用法分析(对比arguments.length)
2016/09/16 Javascript
JavaScript中原型链存在的问题解析
2016/09/25 Javascript
JS中substring与substr的用法
2016/11/16 Javascript
有趣的bootstrap走动进度条
2016/12/01 Javascript
discuz表情的JS提取方法分析
2017/03/22 Javascript
JavaScript你不知道的一些数组方法
2017/08/18 Javascript
VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解
2018/11/30 Javascript
Vue+Element实现动态生成新表单并添加验证功能
2019/05/23 Javascript
js实现小星星游戏
2020/03/23 Javascript
[03:40]DOTA2抗疫特别篇《英雄年代》
2020/02/28 DOTA
python使用ctypes模块调用windowsapi获取系统版本示例
2014/04/17 Python
python批量生成本地ip地址的方法
2015/03/23 Python
python使用matplotlib绘制柱状图教程
2017/02/08 Python
在python中实现调用可执行文件.exe的3种方法
2019/07/07 Python
python selenium 查找隐藏元素 自动播放视频功能
2019/07/24 Python
Python实现朴素贝叶斯的学习与分类过程解析
2019/08/24 Python
关于tf.matmul() 和tf.multiply() 的区别说明
2020/06/18 Python
python 实现批量图片识别并翻译
2020/11/02 Python
Python xlwings插入Excel图片的实现方法
2021/02/26 Python
美国婴童服装市场上的领先品牌:Carter’s
2018/02/08 全球购物
Cynthia Rowley官网:全球领先的生活方式品牌
2020/10/27 全球购物
品管员岗位职责
2013/11/10 职场文书
秋季运动会活动方案
2014/02/05 职场文书
化学专业自荐信
2014/05/28 职场文书
法制宣传口号
2014/06/16 职场文书
公司门卫岗位职责范本
2014/07/08 职场文书
赢在执行观后感
2015/06/16 职场文书
应届毕业生的自我评价
2019/06/21 职场文书
python可视化分析绘制带趋势线的散点图和边缘直方图
2022/06/25 Python