Jesse Reza Khorasanee
Jesse Reza Khorasanee

Reputation: 3471

How to send a npm package's static assets to a nuxt application?

I'm trying to send assets from an npm package to a nuxt application. Has anyone had success doing this?

I have an vue component as an npm package with stucture:

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

This vector image is loaded in the vue component's template in this npm package like so:

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

The above works fine for use when testing this package on it's own.

However when I import the npm package in a nuxt app like so:

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

When I run the app I get a 404 for the svg.

Nuxt looks for the file in http://localhost:3000/_nuxt/img/noun-filter.b16c5666.svg where it does not exist.

Is there something I'm missing here? Why does nuxt change the path of the assets? Why is it not just looking in the node modules like we would expect?

How does one send static assets via an npm package to nuxt?

What I've tried

All of the above had the same result with nuxt looking for the image at: http://localhost:3000/_nuxt/img/noun-filter.b16c5666.svg

Upvotes: 2

Views: 1909

Answers (3)

Jesse Reza Khorasanee
Jesse Reza Khorasanee

Reputation: 3471

For those who find this and none of the other answers work, use vue-svg-inline-loader.

in your component template

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

in vue.config.js

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

Pretty painless and works well for me. It has the downside that your svg's end up bundled with your package but url-loaders will do the same

Upvotes: 0

User 28
User 28

Reputation: 5158

I think there is no easy solution here.

First solution, use url-loader to inline your asset file as a base-64 data url. See 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
  }
...

From Relative Path Imports

Second solution, copy your asset file to static directory and use absolute url instead.

Related post.

Upvotes: 1

Harkal
Harkal

Reputation: 1828

make your assets in a standalone directory static and in your tsconfig.json of your package include the static directory to the rootDirs field like the following example

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

and republish your package and the static files ll also be available

Upvotes: 1

Related Questions