webpack文件夹打包_webpack多入口文件页面打包详解
本文主要介绍了webpack多入口文件页面打包配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望帮助到大家。
大多数情况下,我们使用 webpack来打包单页应用程序,这个时候只需要配置一个入口,一个模板文件,但也不尽是如此,有时候也会碰到多页面的项目,而且以我的经验来看,这种情况出现的频率还不低,例如项目比较大,无法进行全局的把握,或者项目需要多次的更新迭代等,都适合做成多页面程序,这就涉及到了 webpack的多页面文件的打包配置问题。
手动配置
单页应用程序和多页应用程序的 webpack配置文件其实绝大部分都还是相同的,只不过多页的配置需要在单页配置的基础上顾及到多个页面罢了,loader、output、plugins这些基本都不需要改动,需要改动的一般都是入口文件 entry,如果你用到了 抽离css样式的插件 extract-text-webpack-plugin、自动模板插件 html-webpack-plugin的话,那么还需要对这两个插件进行额外的改写,大多数情况下,我们也都只需要改动这三个地方,所以本文就只简单说下这三个位置,如果在实际的项目中还有其他的地方需要改动,参照这三个位置即可。
示例的文件目录如下:
entry
单页应用程序的入口配置一般如下所示:entry: resolve(__dirname, "src/home/index.js")
这个配置就是指定 webpack从 /src/home/index.js这个文件开始进入,进行一系列的打包编译过程。
如果是多页应用程序,则需要多个入口文件,例如:entry: {
home: resolve(__dirname, "src/home/index.js"),
about: resolve(__dirname, "src/about/index.js")
}
这样,整个项目就有了两个入口 home和 about
extract-text-webpack-plugin
extract-text-webpack-plugin 插件主要是为了抽离css样式,防止将样式打包在 js中引起页面样式加载错乱的现象,单页程序中,一般这样使用此插件:plugins: [
new ExtractTextPlugin('style.[contenthash].css')
]
而到了多页程序,因为存在多个入口文件以及对应的多个页面,每个页面都有自己的 css样式,所以需要为每个页面各自配置一下:plugins: [
new ExtractTextPlugin('home/[name].[contenthash].css'),
new ExtractTextPlugin('about/[name].[contenthash].css')
]
除此之外还需要注意一点,每个页面也只需要自己的 css样式,理论上把别的页面 css样式文件也打包到自己的页面中当然也是可以的,但显然是不合理的,这只会增加冗余代码,还可能会导致不可预测的样式覆盖等问题,所以需要对下面这种 loader配置进行修改:{
test: /\.css$/,
loader: 'style!css!autoprefixer'
},
{
test: /\.scss$/,
loaders: [
'style',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
'sass',
'autoprefixer'
]
},
上面的配置会把所有编译出来的 css文件打包到同一个文件中,我们要做的就是把这些 css分离开,每个页面都有各自单独的 css样式文件:// 为每个页面定义一个 ExtractTextPlugin
const homeExtractCss = new ExtractTextPlugin('home/[name].[contenthash].css')
const aboutExtractCss = new ExtractTextPlugin('about/[name].[contenthash].css')
// ...
module: {
rules: [
// 每个页面的 ExtractTextPlugin 只处理这个页面的样式文件
{
test: /src(\\|\/)home(\\|\/)css(\\|\/).*\.(css|scss)$/,
use: homePageExtractCss.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader', 'sass-loader']
})
},
{
test: /src(\\|\/)about(\\|\/)css(\\|\/).*\.(css|scss)$/,
use: salePersonalCenterExtractCss.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader', 'sass-loader']
})
}
]
}
// ...
// 每个页面都有各自的 ExtractTextPlugin,所以需要都声明一遍
plugins: [
homeExtractCss,
aboutExtractCss
]
html-webpack-plugin
html-webpack-plugin插件的使用,在单页应用程序和多页应用程序中的 webpack配置没什么区别new HtmlWebpackPlugin({
filename: 'home/home.html',
template: 'src/home/html/index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true
}
})
new HtmlWebpackPlugin({
filename: 'about/about.html',
template: 'src/about/html/index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true
}
})
有几个页面,就对每个页面进行上述配置即可。
自动配置
上述的配置代码已经可以满足多页面开发需求了,但是有一点似乎有些遗憾,那就是每增加一个页面,就需要更新一遍 entry、extract-text-webpack-plugin、HtmlWebpackPlugin的配置,虽然只是几行代码的问题,而且基本上都是复制粘贴没什么难度,但毕竟代码再少也需要过问,并且需要改的地方比较多,仓促之下可能还会遗漏,要是能一劳永逸,写一遍代码,无论以后增删页面都不需要过问就好了。
稍微观察下这个目录就可以发现,这个目录结构其实是很有规律的:
每个页面都是 src/目录下的一个文件夹,这个文件夹中有两个子目录,分别存放这个页面的模板 html,样式文件 css,还有一个入口文件 index.js
既然有规则,那么肯定是可以进行程序编码的,如果按照这种规则,每个页面都是 ./src下的一个目录,目录名即为页面名,并且这个目录中的结构也都是相同的,那么可以通过一个通用方法来获取所有的页面名称(例如 home、about),这个通用方法的一个示例如下:function getEntry () {
let globPath = 'src/**/html/*.html'
// (\/|\\\\) 这种写法是为了兼容 windows和 mac系统目录路径的不同写法
let pathDir = 'src(\/|\\\\)(.*?)(\/|\\\\)html'
let files = glob.sync(globPath)
let dirname, entries = []
for (let i = 0; i < files.length; i++) {
dirname = path.dirname(files[i])
entries.push(dirname.replace(new RegExp('^' + pathDir), '$2'))
}
return entries
}
借助 glob这个库,遍历 .src/目录下具有这种规律 src/**/html/*.html的子目录,通过正则匹配出这个子目录的名称
获取到了所有的页面名称,下面就好办了。
entry// entry: resolve(__dirname, "src/home/index.js")
// 改为
entry: addEntry()
//...
function addEntry () {
let entryObj = {}
getEntry().forEach(item => {
entryObj[item] = resolve(__dirname, 'src', item, 'index.js')
})
return entryObj
}
extract-text-webpack-plugin// plugins: [
// new ExtractTextPlugin('home/[name].[contenthash].css'),
// new ExtractTextPlugin('about/[name].[contenthash].css')
//]
// 改为
const pageExtractCssArray = []
getEntry().forEach(item => {
pageExtractCssArray.push(new ExtractTextPlugin(item + '/[name].[contenthash].css'))
})
// ...
plugins: [...pageExtractCssArray]
module.rules样式相关的两个loaders删掉,改为动态添加:getEntry().forEach((item, i) => {
webpackconfig.module.rules.push({
test: new RegExp('src' + '(\\\\|\/)' + item + '(\\\\|\/)' + 'css' + '(\\\\|\/)' + '.*\.(css|scss)$'),
use: pageExtractCssArray[i].extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader', 'sass-loader']
})
})
})
// ...
module.exports = webpackconfig
html-webpack-plugin
plugins中无需手动初始化 html-webpack-plugin,改为动态添加:getEntry().forEach(pathname => {
let conf = {
filename: path.join(pathname, pathname) + '.html',
template: path.join(__dirname, 'src', pathname, 'html', 'index.html')
}
webpackconfig.plugins.push(new HtmlWebpackPlugin(conf))
})
// ...
module.exports = webpackconfig
完成了上述修改后,以后无论是在项目中添加页面还是删除页面,都无需再对 webpack配置进行手动修改了,虽然开始时开起来似乎这种动态的自动配置代码比较多,而且稍微复杂一点,但是从长期来看,绝对是一劳永逸的好做法。
另外,如果你的项目目录结构和我示例的目录结构不一样,那么就需要你根据自己的目录结构对代码进行少许的修改,但整体解决问题的方法是不变的,一个易于维护的项目,目录结构都该是有律可循的。
相关推荐:
webpack文件夹打包_webpack多入口文件页面打包详解相关推荐
- Linux 命令利用scp实现从服务器共享地址上传下载文件、文件夹实例演示,scp命令的参数详解
传文件的话,不用参数 -r,文件夹用参数 -r 语法:scp [可选参数] 原地址 目的地址 我下面演示的是传文件: scp -r root@192.x.x.x:/data/disk/20200520 ...
- linux查看某个文件夹的大小(ls命令、du命令详解)
ls 命令:列出当前工作目录下的所有文件/文件夹的名称 使用ls -l,会显示成字节大小,ls- lh会以KB.MB等为单位进行显示更加直观. du 命令:查看当前目录和子目录文件夹/文件大小情况 d ...
- java读取文件夹下的所有txt文件,java读取文件夹下文件及txt内容
public class PositionController { // 读取txt内容 public static String txt2String(File file) { StringBuil ...
- .Net读取XP文件夹中的Thumbs.db文件
一般在XP文件夹里面,特别是图片和视频文件夹里有一个文件-Thumbs.db文件.这个文件是XP用来缓存图片和影音文件的缩略图的,有了这个文件,XP在打开保存大量图片文件的文件夹的时候,显示速度会明显 ...
- java实现zip压缩文件(同一文件夹下的多个文件夹打成一个zip包)
这2个工具类都推荐使用统一个场景的不通过写法 推荐第一种 package com.gblfy.test;import java.io.BufferedInputStream; import java. ...
- VB 打开文件夹,并选中指定的文件
标记一下,以防忘记. 这个功能比较方便,在打开文件夹时自动选中目标项,迅雷下载文件完成后的"打开文件夹"功能就是这样. 实现方面很简单,就是在调用EXPLORER时加个/Selec ...
- 服务器系统c盘在哪个文件夹,windows操作系统放在哪个文件夹下
2010-05-22 回答 windows文件夹下的文件名解释 一.文件夹篇 all users 这里记录的是window的用户以及这些用户个人设定的开始菜单及桌面等信息. command 在这个目录 ...
- xml遍历文件夹vector_怎么统计指定文件夹下含有.xml格式的文件数目
如何统计指定文件夹下含有.xml格式的文件数目?如题 ------解决思路----------------------Directory.GetFiles(@"路径", " ...
- linux maven .m2文件夹,maven本地仓库.m2文件夹路径讲解
Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Depen ...
最新文章
- struts2 ognl 判断数据类型_新华三攻防系列之防护篇从防护角度看Struts2历史漏洞...
- 如何使用十进制range()步长值?
- 第十一届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学B组
- Games101现代图形学入门Lecture 3: Transformation知识点总结
- .net core实践系列之短信服务-Api的SDK的实现与测试
- ADF任务流:页面片段的托管bean范围
- linux svn启动失败,linux svn authorization failed错误
- Spark推荐系列之Word2vec算法介绍、实现和应用说明(附代码)
- 一步一坑学android之禁用Appt2(andriod studio3.0)
- python投注_python练习 | 下注猜大小 | 入门级
- svn安装以及初步使用
- 查看页面密码框明文密码
- 选手投票html,选手投票网页制作
- APP崩溃的主要原因
- JAVA SE 实战篇 C7 基于CSFramework的聊天室 (下) 客户端APP
- 【数智化案例展】某人民医院——智慧医疗大数据建设
- 利用python将excle表格由xls转换为xlsx格式
- 软件开发项目 质量管理的6大关键事项
- 2019——区块链从业者的集体冬眠
- 转行学java好学吗?完全没有经验怎么办?
热门文章
- STM32工作笔记005---STM32芯片解读
- SpringCloud工作笔记067---消息推送_推送视频_推送图片_在通知栏里显示图片视频_自定义点击消息后的动作
- Maven异常总结002---nexus服务器启动失败wrapper | The nexus service was launched, but failed to start.
- paper reading: roi 区域对人脸测试心率有用
- 杭电1166敌兵布阵(线段树)
- php 解决跨域问题
- 左右法则 来解析指针问题
- java web应用开发渐进教程_Java Web应用开发渐进教程
- 流星雨_行者常至 双子座流星雨
- linux 将当前时间往后调整2分钟_【转】修改LINUX时间