【问题标题】:How to send a npm package's static assets to a nuxt application?如何将 npm 包的静态资产发送到 nuxt 应用程序?
【发布时间】:2020-11-03 06:08:11
【问题描述】:

我正在尝试将资产从 npm 包发送到 nuxt 应用程序。有没有人成功做到这一点?

我有一个 vue 组件作为带有结构的 npm 包:

-src/
 -assets/
  -noun-filter.svg

这个矢量图像被加载到这个 npm 包中的 vue 组件的模板中,如下所示:

<img class="filter-icon" :src="require('../assets/noun-filter.svg')"/>

当单独测试这个包时,上面的方法很好用。

但是,当我像这样在 nuxt 应用程序中导入 npm 包时:

<script>
export default {
  name: "NuxtMainPage",
  components: {
    NpmImportedComponent: process.client
      ? () => import("@myname/mynpmpackage").then(m => m.Content)
      : null
  },
//...
}
</script>

当我运行应用程序时,我得到了 svg 的 404。

Nuxt 在http://localhost:3000/_nuxt/img/noun-filter.b16c5666.svg 中查找不存在的文件。

这里有什么我遗漏的吗?为什么nuxt会改变资产的路径?为什么它不像我们期望的那样只查看节点模块?

如何通过 npm 包将静态资源发送到 nuxt?

我尝试过的

  • 尝试在我的应用程序中使用 url-loader。网址仍然在 nuxt 中被重定向
  • 在 nuxt 应用中使用 import @myname/mypackage/src/assets/noun-filter.svg 导入项目
  • 将npm包中的相对url从../assets切换到@assets
  • 将 assets 文件夹移动到 npm 包的根目录,并将其添加到 package.json 中包含的文件中

上述所有结果都与 nuxt 在以下位置查找图像的结果相同: http://localhost:3000/_nuxt/img/noun-filter.b16c5666.svg

【问题讨论】:

    标签: javascript vue.js nuxt.js npm-package


    【解决方案1】:

    我认为这里没有简单的解决方案。

    第一个解决方案,使用 url-loader 将您的资产文件内联为 base-64 数据 URL。见Asset URL Handling

    vue.config.js

    ...
      chainWebpack: config => {
        config.module
          .rule('images')
            .use('url-loader')
              .loader('url-loader')
              .tap(options => Object.assign(options, { limit: 10240 })) // default is 4096
      }
    ...
    

    来自Relative Path Imports

    第二种解决方案,将你的资产文件复制到static 目录并改用绝对网址。

    Related post.

    【讨论】:

    • 感谢@User 28 的帮助!我刚刚尝试了上述方法并切换到绝对网址,但不幸的是两者都不起作用。我开始怀疑是异步 process.client ? ... 导入导致了问题,接下来会尝试测试。
    • 对于第一个解决方案,请确保您的文件大小不超过限制。然后在运行 build 之后,您将看不到 img 目录。而且您必须在组件而不是您的应用程序上运行构建。使用其他 npm 包时也是如此。
    • 对于第二种解决方案,../assets@assets 不是绝对路径。如果您使用 vue-cli,您必须将该资产文件放入公共目录,然后使用 /icon.svg 然后构建,webpack 将不会对这个绝对路径执行任何操作。将该 public 复制到您的应用程序中,即 nuxt 中的 static 目录。
    • @JesseRezaKhorasanee
    【解决方案2】:

    在独立目录static 中创建您的资产,并在您的包的tsconfig.json 中将static 目录包含到rootDirs 字段中,如下例所示

    {
        ...
        "compilerOptions": {
            ...
            "rootDirs": [
                "src",
                "static",
                ...
            ]
            ...
        }
        ...
    }
    

    并重新发布您的包,静态文件也将可用

    【讨论】:

    • 感谢您的帮助!我试过这个,不幸的是它没有用。我没有在我的 npm 包中使用 typecipt,所以也许 tsconfig.json 没有被使用?
    • 你应该将你的包迁移到 ts。它功能强大且易于其他开发人员使用,因为它提供了额外的声明文件
    • 在您的情况下,您可以在发布之前手动将这些文件添加到您的包中
    • 我刚查了一下,tsconfig.json 和 /static 中的所有文件都在那里,我的 nuxt 应用仍然找不到它们
    • @JesseRezaKhorasanee 看看这个 => nuxtjs.org/api/configuration-modules
    【解决方案3】:

    对于那些发现这个并且其他答案都不起作用的人,请使用vue-svg-inline-loader

    在您的组件模板中

    <img svg-inline src="'@/../assets/noun-filter.svg'"/>
    

    vue.config.js

    //...
          config.module
            .rule('vue')
            .use("vue-svg-inline-loader")
            .loader("vue-svg-inline-loader") 
    //...   
    

    非常无痛,对我来说效果很好。它的缺点是你的 svg 最终会与你的包捆绑在一起,但 url-loaders 也会这样做

    【讨论】:

      猜你喜欢
      • 2014-05-25
      • 2016-11-04
      • 1970-01-01
      • 2021-05-10
      • 2023-03-29
      • 2017-09-01
      • 1970-01-01
      • 2014-12-19
      • 2018-05-20
      相关资源
      最近更新 更多