Élodie Petit
Élodie Petit

Reputation: 5914

Webpack external library access with Vue web components

I create a web component with vue-cli.3 in order to use it in other projects with the following command:

vue-cli-service build --target lib --name helloworld ./src/components/HelloWorld.vue

The component has a dependency on lodash. I don't want to bundle lodash with the component because lodash is going to be provided by the host application, so I configure webpack in vue.config.js like below:

module.exports = {
    configureWebpack: {
        externals: {
            lodash: 'lodash',
            root: '_'
        }
    }
}

So this way, I successfully compile the component without lodash.

In the host application (the one that will use the component), I add the source path of the newly created and compiled component into index.html:

<script src="http://localhost:8080/helloworld.umd.js"></script>

Register the component in App.vue:

<template>
    <div id="app">
        <demo msg="hello from my component"></demo>
    </div>
</template>

<script>
export default {
    name: "app",
    components: {
        demo: helloworld
    }
};
</script>

The helloworld component renders without problems. Every feature of the component works without problems but as soon as I call a method of lodash, I get;

Uncaught TypeError: Cannot read property 'camelCase' of undefined

which means the component cannot access the lodash library that the host application uses.

I need to find a way to use the already bundled libraries in the host application from the components.

Is there a way?

Upvotes: 5

Views: 6105

Answers (1)

tony19
tony19

Reputation: 138216

The Vue config you used should work (see GitHub demo), so maybe there's something missing in your setup. I've listed the pertinent steps to arrive at the demo:

  1. In public/index.html of a VueCLI-generated project, import Lodash from CDN with:

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
    
  2. In the library component (src/components/HelloWorld.vue), the _ global can be used without importing lodash. For example, display a computed property that formats the msg prop with _.camelCase.

  3. To avoid lint errors, specify _ as an ESLint global (/* global _ */).

  4. In vue.config.js, configure Webpack to externalize lodash:

    module.exports = {
      configureWebpack: {
        externals: {
          lodash: {
            commonjs: 'lodash',
            amd: 'lodash',
            root: '_' // indicates global variable
          }
        }
      }
    }
    
  5. In package.json, edit the build script to be:

    "build": "vue-cli-service build --target lib --name helloworld ./src/components/HelloWorld.vue",
    
  6. Run npm run build, and then edit dist/demo.html to also include the <script> tag above.

  7. Start an HTTP server in dist (e.g., python -m SimpleHTTPServer), and open dist/demo.html. Observe the effect of _.camelCase (from step 2) without console errors.

GitHub demo

Upvotes: 4

Related Questions