likes
comments
collection
share

聊聊webpack多页面应用如何打包

作者站长头像
站长
· 阅读数 51

这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

介绍

相信大家经常构建的多为单页面应用(SPA),但是还有一种应用叫多页面应用(MPA),也就,每一次页面跳转的时候,后台服务器都会返回一个新的html文档,这样类型的网站也叫多页网站。这是前端早期没形成工程化模块化之前普遍都可以见到的,跟单页面应用相比,它的优势就是页面直接是解耦的,还有一个最大的优势就是对seo非常的友好。

也许,你碰到一些场景需求必须要进行多页面打包,如,一些H5一系列独立的小活动等,本期就带大家对多页面应用打包去进行一个了解,并且实现出一个通用的多页面打包方案。

准备

我们先做下准备工作,这里先建一个文件夹pages,里面先放入两个不同名字的页面模块,如下图:

聊聊webpack多页面应用如何打包

然后要写webpack.config.js了,至于一些里面基础配置不在今天的讲解范围,就不一一赘述了。

实现

// webpack.config.js
const entry = {
  "index": path.resolve(__dirname, "pages/index/index.js"),
  "login": path.resolve(__dirname, "pages/login/login.js")
}
const plugins = [
  new CleanWebpackPlugin(),
  new HtmlWebpackPlugin({
    filename: "index.html",
    template: path.resolve(__dirname, "pages/index/index.html"),
    chunks:["index"],
    inject:true,
    minify:{
      html5:true,
      minifyCSS:true,
      minifyJS:true,
      removeComments:false,
      preserveLineBreaks:false
    }
  }),
  new HtmlWebpackPlugin({
    filename: "page.html",
    template: path.resolve(__dirname, "pages/login/login.html"),
    chunks:["login"],
    inject:true,
    minify:{
      html5:true,
      minifyCSS:true,
      minifyJS:true,
      removeComments:false,
      preserveLineBreaks:false
    }
  }),
]
module.exports =  {
  entry,
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: "js/[name].[chunkhash:8].js",
  },
  plugins,
  // ...more
}

其实就是控制entry入口配置和增加HtmlWebpackPlugin实例就可以完成,然后我们运行npm run build进行打包。

聊聊webpack多页面应用如何打包

可以看到打包的结果的确分离出了不同页面,每个页面又有自己的逻辑单元。

但是问题也来了,如果我们页面非常之多怎么办?不能每个页面都要手动配置一遍吧。通过上面的代码,你会发现,很多配置都是相似的,或许我们可以进行组合一次性打包处理,接下来,就要做一个多页面应用的打包方案喽~

改进

遍历之前,我们必须要拿到pages下有多少个页面应用,我们可以用node的fs.readdirSync方法去获取,但我们这里准备去安装一个glob,通过glob.sync可以轻松的把每个文件名匹配处理。

# NPM
npm i -D glob
# YARN 
yarn add -D glob
const glob = require("glob")
const entryFiles =  glob.sync(path.resolve(__dirname,"./pages/*/*.html"))

我们通过glob就非常轻松匹配得到了pages相应的文件地址数组。后面,我们就可以利用这些信息进行遍历出来,然后塞到入口和插件集合中。

const glob = require("glob")

const entryFiles = glob.sync(path.resolve(__dirname, "./pages/*/*.html"))
const entry = {}
const plugins = [
  new CleanWebpackPlugin(),
  //  ...more plugin
]

entryFiles.forEach(_html => {
  const _name = _html.match(/pages\/(.*)\//)[1]
  entry[_name] = path.resolve(__dirname, `pages/${_name}/${_name}.js`)
  const _htmlPage = new HtmlWebpackPlugin({
    filename: _name + ".html",
    template: path.resolve(__dirname, `pages/${_name}/${_name}.html`),
    chunks: [_name],
    inject: true,
    minify: {
      html5: true,
      minifyCSS: true,
      minifyJS: true,
      removeComments: false,
      preserveLineBreaks: false
    }
  })
  plugins.push(_htmlPage)
})

这里就算改造完成了,我们再往上加一个页面mine,然后执行打包下看看返回结果是否符合期望。

聊聊webpack多页面应用如何打包

聊聊webpack多页面应用如何打包

可以看到经过这样的改进后,再怎么增加页面都可以不用每次繁琐的一遍遍的去写相关的entry和plugins配置代码了。

结语

今天带大家简单学习了多页面应用打包,很容易吧,当然,可以看出多页面打包的通用处理固然方便,但也要遵循特定的规律去创建不同的页面才行,我们后面如果有需要还可以通过自定义一些页面参数去更好的扩展它,使它更健壮。最后说句,多页面应用虽然有过场跳转白页影响一些体验,但考虑好业务场景再去使用,衡量利弊,也是不错的。