webpack多页面方案

本文探讨了两种有效的Webpack代码拆分方法:使用react-loadable结合import()动态导入模块,以及利用entry配置和html-webpack-plugin的chunks选项。前者适用于单页应用,能按需加载组件,但需手动维护路由数组;后者通过配置多个入口文件和模板,自动处理代码分割,适合多页面应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇总结了webpack的配置,其实配置还是相对容易的,因为只要根据需要照搬选项就好了,但是只写配置项那最终打包出来的结果就是一个html和一个js,如果页面多了那肯定是不行的,所以就需要想办法拆分代码,我所知道的拆分代码方式大概有2种:1.使用react-loadable + import();2.entry的对象写法和html-webpack-plugin的chunks选项;

参考文章比较多
https://www.cnblogs.com/wmhuang/p/8967639.html
https://blog.51cto.com/13869008/2167792
https://blog.youkuaiyun.com/hongchh/article/details/55113751
https://www.jianshu.com/nb/27964463
https://segmentfault.com/a/1190000005770042
https://blog.youkuaiyun.com/yeluochen4869/article/category/7540543

方案1

react-loadable + import()
这个方案需要@babel/plugin-syntax-dynamic-import的支持,记得修改babelrc。一般用这个方案的话是要用react-router来写一个单页应用,模板加载一个入口js,入口js里把页面路由写好,每个页面作为一个组件,然后写一个类似这样的结构

import Loadable from 'react-loadable';

const routeArr = [
  {
    path: '/page1',
    component: Loadable({
      loader: () =>
        import(
          /* webpackChunkName: "page1" */
          './page1'
        ),
      loading: <div>loading...</div>
    })
  },
  {
    path: '/page2',
    component: Loadable({
      loader: () =>
        import(
          /* webpackChunkName: "page2" */
          './page2'
        ),
      loading: <div>loading...</div>
    })
  }
]

// 其他部分省略了
render() {
    return (
      <Switch> // 用Switch而不是Router可以保证只匹配到一个路径
        {routeArr.map((v, k) => {
          return <Route key={k} path={`/${v.path}`} component={v.component} />;
        })}
      </Switch>
    );
  }

这个方案的问题在于,/* webpackChunkName: "page2" */这个注释,这个注释不加,动态import是不生效的,即使生效,也不能通过写一个循环来把所有的页面组件都循环import,也就是说,每添加一个页面组件,就要自己往routeArr里加一段代码,当然可以通过别的方式来生成这个routeArr,比如写文件方式,根本问题就是routeArr要以硬编码形式存在,而不能是这样的

const routeArr = ['page1', 'page2'].map((v, k)=>{
    return {
    path: `/${v}`,
    component: Loadable({
      loader: () =>
        import(`./${v}`),
      loading: <div>loading...</div>
    })
  };
})

这个方案的优点在于,1.不需要多个html模板,是个标准的单页应用;2.不需要多个html-webpack-plugin实例;3.工程路径可以随意,只要写到路由数组里的时候自己确定是对的就可以,不需要统一,但是作为一个工程当然是统一为好;4.写一些页面共有的组件,比如菜单,顶部导航等比较简单

方案2

webpack的入口配置这样写

entry: {
    page1:"./src/page1.js",
    page2:"./src/page2.js"
},
output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name]_[contenthash].js' // 这里如果用hash,每个文件的hash是一样的,所以要用内容hash
}

html-webpack-plugin插件这样来写

const HtmlWebpackPlugin = require("html-webpack-plugin");

plugins: [
    new HtmlWebpackPlugin({
        filename: "page1.html", 
        template: "./src/page1.html",}),
        chunks: ["page1"]
    }),
    new HtmlWebpackPlugin({
        filename: "page2.html",
        template: "./src/page2.html",}),
        chunks: ["page2"]
    })
]

注意创建HtmlWebpackPlugin实例时的chunks选项,这个选项如果不写,默认会把entry里生成的所有文件全部注入到每个HtmlWebpackPlugin实例里去,为了出这个坑我看了好多篇文章

这个方案的优点在于,不用每次手写添加的页面的名称和路由(对比方案1),只要按照约定的工程目录创建页面,就可以通过遍历目录生成入口和HtmlWebpackPlugin实例来打包,缺点是页面多的情况下HtmlWebpackPlugin实例也很多,应该会影响性能,并且如果要写一些页面上都有的组件(比如菜单和导航),就要在每个页面里自己引用

方案3

如果觉得多个html-webpack-plugin实例的方式不靠谱,可以把方案2改改,还是配多个entry,工程目录也一样,然后自己写一个路由,根据当前加载的url来判断加载哪个js,这样其实就和方案1很类似了,这个路由写在服务端会比较好,可以提前设置好js的链接,也可以实现页面权限之类的需求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值