【问题标题】:Is there a way to specify multiple public directories with static assets with webpack?有没有办法用 webpack 指定多个带有静态资产的公共目录?
【发布时间】:2021-11-21 17:47:46
【问题描述】:

我有一个 Vue 项目,它具有从 Vue CLI 生成的标准 webpack 配置。这给出了项目目录结构,例如:

public\
  css\
  images\
  index.html
src\
tests\
package.json
etc...

所以默认的静态资产目录是项目目录根目录下的public\。现在我想指定另一个静态目录(它将位于src\ 中的某处),以便在构建时合并这两个目录的内容。如果文件冲突,src\ 中的文件应该覆盖public\ 中的文件。

如何使用 webpack 做到这一点?

我需要这个的原因是因为我想为不同的客户制作单独的版本。每个客户都将拥有自己的特定资产和组件,我计划将它们放在src\ 的某个位置。例如:

public\             // shared static assets
src\
   components\      // shared stuff for all customers
   store\
   ...etc        

   customer1\       // customer1 specific stuff below this level
      public\       // merge these with shared static assets and overwrite if necessary
      components\
      store\
      index.js

   customer2\       // customer2 specific stuff below this level
      public\
      components\
      store\
      index.js

因此,当我运行 npm run build --customer=customer1 时,我只想在捆绑包中获取 shared + customer1 的东西。我几乎通过webpack alias config 为客户的组件、商店和其他非静态内容解决了这个问题,我想知道如何为public 目录中的静态资产做到这一点?

【问题讨论】:

    标签: javascript reactjs vue.js webpack frontend


    【解决方案1】:

    这不是 Webpack 的工作方式。当你编译你的应用程序时,Webpack 做的第一件事就是扫描你的代码并构建一个依赖树。实际上,依赖关系可以是很多东西,但可以将它们视为您的“导入文件”。

    扫描从您的入口点开始,通常是src/index.js,然后从那里递归进行。我想明确的是,只有“显式”依赖被捆绑,其他任何东西都将被忽略。换句话说,如果你不导入某些东西并且有一个特定的加载器,那么该资产将不会被捆绑。

    同样,Webpack 不会扫描您的src 目录,而是从其入口点遍历您的应用程序。

    还要考虑到,通过良好的设置(如 Create React App 中包含的设置),几乎每个资产都将转换为 JS 模块并合并为具有特定命名约定的块,以允许缓存失效。也就是说,名字冲突的可能性很小。

    鉴于您的情况,我非常、非常、非常、非常强烈地建议您为每个不同的客户使用不同的存储库。如果您需要重用组件,请编写一个库。如果您需要重用资产,请对其进行优化并将其托管在 CDN 上。我预计您的方法会出现安全性、可维护性和可扩展性问题。

    最后,如果您坚持,一种可行的方法是将自定义插件附加到您的 src 目录中的那些“静态”目录(如果已经有可用的,您可以四处搜索,如果没有,请参阅自定义插件在 Webpack 文档中,它并不是那么简单)。该插件基本上会根据环境变量或传递的选项更改导入文件的路径。

    如果我忽略了某些东西,请告诉我,但我真的认为你应该将项目分开,即使“基础”是相同的。

    最后一点:您的方法可能会破坏任何静态分析(忘记 TypeScript、Flow、JSDocs、IDE 自动完成和提示等)。您还将打破模块化编程范式。这尤其适用于组件。对于图像等其他媒体资产,限制会更少,但仍然会遇到问题。您的应用程序将如何在开发模式下运行?充其量你会遇到性能问题。您可以破坏 HMR(热模块更换)、应用程序测试......我会在这里停下来。

    【讨论】:

    • 嘿,感谢详细的回答和努力,但我有一些经验,知道 webpack 如何工作和构建图树。我已经设法根据上面显示的项目结构和可以从 cmd 行获取并转换为客户子目录的 env 变量为每个客户创建独立的构建。然后我像import customerApi from '#customer#' 一样引用它,其中#customer# 是通过webpack alias 配置指定的。所以这一切都很好,并且适用于开发和产品构建,HMR 等......不用担心。我现在需要弄清楚静态资产。
    • @mlst 你在类型检查、自动完成等方面没有问题吗?但是,对于其他问题,我指的是创建一个插件来替换路径的想法。
    • @mlst 我现在不明白的是你为什么不对这些静态资产做同样的事情?使用 Webpack 时几乎可以导入所有内容(媒体文件、JSON 文件、文档等),有什么问题?
    • 静态资产的处理方式与其他通过插件转换的东西不同。静态数据不由 webpack (afaik) 处理,它们只是从 web 应用程序中按原样使用。我可能会创建一个插件,将客户特定的静态资产与共享的资产合并,但我想知道这是否已经通过一些配置实现,所以我不必重新发明轮子。
    • @mlst 请参阅官方文档中的Asset Management。显式导入到您的代码中的静态资产(就像您对 React 组件所做的那样)被视为与任何其他导入的资源一样。也许会涉及不同的加载器/插件,但基本逻辑是相同的。因此,您也可以为静态资产使用别名。严格来说,如果没有从服务器获取数据,那么前端中的所有内容都是“静态的”,而不仅仅是图像和类似的东西。
    猜你喜欢
    • 2011-10-24
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 2020-08-03
    相关资源
    最近更新 更多