详解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 相关文章推荐
javascript 折半查找字符在数组中的位置(有序列表)
Dec 09 Javascript
两种方法基于jQuery实现IE浏览器兼容placeholder效果
Oct 14 Javascript
Node.js编程中客户端Session的使用详解
Jun 23 Javascript
基于jQuery实现鼠标点击导航菜单水波动画效果附源码下载
Jan 06 Javascript
详解JS正则replace的使用方法
Mar 06 Javascript
jQuery插件AjaxFileUpload实现ajax文件上传
May 05 Javascript
js验证框架实现代码分享
May 18 Javascript
JQ中$(window).load和$(document).ready区别与执行顺序
Mar 01 Javascript
ES6正则的扩展实例详解
Apr 25 Javascript
vue学习之mintui picker选择器实现省市二级联动示例
Oct 12 Javascript
Vue.js的复用组件开发流程完整记录
Nov 29 Javascript
Vue图片裁剪组件实例代码
Jul 02 Vue.js
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+mysql事务rollback&amp;commit示例
2010/02/08 PHP
php的字符串用法小结
2010/06/08 PHP
php语言中使用json的技巧及json的实现代码详解
2015/10/27 PHP
PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
2016/01/07 PHP
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
display和visibility的区别示例介绍
2014/02/26 Javascript
详谈jQuery操纵DOM元素属性 attr()和removeAtrr()方法
2015/01/22 Javascript
简单实现兼容各大浏览器的js复制内容到剪切板
2015/09/09 Javascript
js接收并转化Java中的数组对象的方法
2016/08/11 Javascript
总结十个Angular.js由浅入深的面试问题
2016/08/26 Javascript
jquery无法为动态生成的元素添加点击事件的解决方法(推荐)
2016/12/26 Javascript
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
2017/02/27 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
2018/09/03 Javascript
vue 引用自定义ttf、otf、在线字体的方法
2019/05/09 Javascript
mpvue 页面预加载新增preLoad生命周期的两种方式
2019/10/17 Javascript
使用konva和vue-konva库实现拖拽滑块验证功能
2020/04/27 Javascript
[03:15]2014DOTA2国际邀请赛 专访国士无双信心满满
2014/07/12 DOTA
Djang中静态文件配置方法
2015/07/30 Python
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
对pandas中iloc,loc取数据差别及按条件取值的方法详解
2018/11/06 Python
PyGame贪吃蛇的实现代码示例
2018/11/21 Python
python 读取dicom文件,生成info.txt和raw文件的方法
2019/01/24 Python
浅谈pytorch grad_fn以及权重梯度不更新的问题
2019/08/20 Python
Django文件上传与下载(FileFlid)
2019/10/06 Python
pytorch sampler对数据进行采样的实现
2019/12/31 Python
python怎么调用自己的函数
2020/07/01 Python
美国班级戒指、帽子和礼服、毕业产品、年鉴:Balfour
2018/11/01 全球购物
医务人员竞聘职务自我评价分享
2013/11/08 职场文书
业务副厂长岗位职责
2014/01/03 职场文书
党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
医学专业大学生职业生涯规划书
2014/10/25 职场文书
事业单位考察材料范文
2014/12/25 职场文书
2015学生会文艺部工作总结
2015/04/03 职场文书
Java org.w3c.dom.Document 类方法引用报错
2021/08/07 Java/Android
Ruby处理CSV数据方法详解
2022/04/18 Ruby
PostgreSQL出现死锁该如何解决
2022/05/30 PostgreSQL