详解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 学习入门篇附实例代码
Mar 16 Javascript
JS兼容浏览器的导出Excel(CSV)文件的方法
May 03 Javascript
jQuery+PHP打造滑动开关效果
Dec 16 Javascript
对象题目的一个坑 理解Javascript对象
Dec 22 Javascript
基于jQuery插件实现点击小图显示大图效果
May 11 Javascript
Node.js服务器环境下使用Mock.js拦截AJAX请求的教程
May 23 Javascript
浅谈JavaScript函数的四种存在形态
Jun 08 Javascript
总结AngularJS开发者最常犯的十个错误
Aug 31 Javascript
支持移动端原生js轮播图
Feb 16 Javascript
纯js实现图片匀速淡入淡出效果
Aug 22 Javascript
利用VS Code开发你的第一个AngularJS 2应用程序
Dec 15 Javascript
VUE v-for循环中每个item节点动态绑定不同函数的实例
Sep 26 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
模仿OSO的论坛(三)
2006/10/09 PHP
php header Content-Type类型小结
2011/07/03 PHP
php中将字符串转为HTML的实体引用的一个类
2013/02/03 PHP
php+ajax注册实时验证功能
2016/07/20 PHP
jquery ajax修改全局变量示例代码
2013/11/08 Javascript
javascript数组去重小结
2016/03/07 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
2016/04/06 Javascript
Bootstrap 表单验证formValidation 实现表单动态验证功能
2017/05/17 Javascript
JavaSctit 利用FileReader和滤镜上传图片预览功能
2017/09/05 Javascript
微信小程序上传图片到服务器实例代码
2017/11/07 Javascript
JavaScript的setter与getter方法
2017/11/29 Javascript
Vue多种方法实现表头和首列固定的示例代码
2018/02/02 Javascript
React中如何引入Angular组件详解
2018/08/09 Javascript
详解javascript对数组和json数组的操作
2019/04/15 Javascript
详解JavaScript对数组操作(添加/删除/截取/排序/倒序)
2019/04/28 Javascript
JavaScript编写开发动态时钟
2020/07/29 Javascript
vue实现验证用户名是否可用
2021/01/20 Vue.js
[37:21]完美世界DOTA2联赛PWL S2 Inki vs Magma 第二场 11.22
2020/11/24 DOTA
python根据路径导入模块的方法
2014/09/30 Python
Python使用scrapy采集数据时为每个请求随机分配user-agent的方法
2015/04/08 Python
Python实现时间序列可视化的方法
2019/08/06 Python
Python语法之精妙的十个知识点(装B语法)
2020/01/18 Python
Django 项目通过加载不同env文件来区分不同环境
2020/02/17 Python
python软件都是免费的吗
2020/06/18 Python
Python如何实现机器人聊天
2020/09/10 Python
python常量折叠基础知识点讲解
2021/02/28 Python
纯CSS和jQuery实现的在页面顶部显示的进度条效果2例(仿手机浏览器进度条效果)
2014/04/16 HTML / CSS
AHAVA美国官方网站:死海海泥护肤品牌
2016/10/18 全球购物
美丽的现代设计家具:2Modern
2018/07/26 全球购物
Glamest意大利:女性在线奢侈品零售店
2019/04/28 全球购物
招商业务员岗位职责
2013/12/16 职场文书
2014年党课学习心得体会
2014/07/08 职场文书
2016关于军训的心得体会
2016/01/11 职场文书
anaconda python3.8安装后降级
2021/06/11 Python
与Windows10相比Windows11有哪些改进?值不值得升级?
2021/11/21 数码科技
python如何读取和存储dict()与.json格式文件
2022/06/25 Python