详解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中令你抓狂的魔术变量
Nov 30 Javascript
一个可以显示阴历的JS代码
Mar 05 Javascript
JS仿Windows开机启动Loading进度条的方法
Feb 26 Javascript
JavaScript更改原始对象valueOf的方法
Mar 19 Javascript
JQuery中attr方法和removeAttr方法用法实例
May 18 Javascript
JS实现文档加载完成后执行代码
Jul 09 Javascript
轻松实现js选项卡切换效果
Sep 24 Javascript
使用 jQuery.ajax 上传带文件的表单遇到的问题
Oct 31 Javascript
Jquery EasyUI Datagrid右键菜单实现方法
Dec 30 Javascript
JS实现根据详细地址获取经纬度功能示例
Apr 16 Javascript
JS回调函数原理与用法详解【附PHP回调函数】
Jul 20 Javascript
如何使用JavaScript检测空闲的浏览器选项卡
May 28 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
这部番真是良心,画质好到像风景区,剧情让人跟着小公会热血沸腾
2020/03/10 日漫
如何去掉文章里的 html 语法
2006/10/09 PHP
PHP7新特性之抽象语法树(AST)带来的变化详解
2018/07/17 PHP
laravel按天、按小时,查询数据的实例
2019/10/09 PHP
jquery蒙版控件实现代码
2010/12/08 Javascript
深入了解Node.js中的一些特性
2014/09/25 Javascript
javascript中返回顶部按钮的实现
2015/05/05 Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
2016/05/31 Javascript
jquery实现瀑布流效果 jquery下拉加载新数据
2016/12/12 Javascript
bootstrap datetimepicker实现秒钟选择下拉框
2017/01/05 Javascript
js实现登录框鼠标拖拽效果
2017/03/09 Javascript
vue-axios使用详解
2017/05/10 Javascript
js评分组件使用详解
2017/06/06 Javascript
详解Vue.js项目API、Router配置拆分实践
2018/03/16 Javascript
element ui table 增加筛选的方法示例
2018/11/02 Javascript
vue中的适配px2rem示例代码
2018/11/19 Javascript
vue+高德地图写地图选址组件的方法
2019/05/18 Javascript
vue视频播放插件vue-video-player的具体使用方法
2019/11/08 Javascript
区分vue-router的hash和history模式
2020/10/03 Javascript
python安装Scrapy图文教程
2017/08/14 Python
Django框架中序列化和反序列化的例子
2019/08/06 Python
Python列表删除元素del、pop()和remove()的区别小结
2019/09/11 Python
python web框架Flask实现图形验证码及验证码的动态刷新实例
2019/10/14 Python
Python+Redis实现布隆过滤器
2019/12/08 Python
Python控制台实现交互式环境执行
2020/06/09 Python
Scrapy爬虫文件批量运行的实现
2020/09/30 Python
css3动画效果抖动解决方法
2018/09/03 HTML / CSS
英国女士和男士时尚服装网上购物:Top Labels Online
2018/03/25 全球购物
Why do we need Unit test
2013/01/03 面试题
三个儿子教学反思
2014/02/03 职场文书
人力资源本科毕业生求职信
2014/06/04 职场文书
2014年四风问题个人对照自查剖析材料
2014/09/15 职场文书
工作时间调整通知
2015/04/24 职场文书
2015年九一八事变纪念活动实施方案
2015/05/06 职场文书
心得体会格式及范文
2016/01/25 职场文书
Python中的pprint模块
2021/11/27 Python