5

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?

7
  • Looking at the webpack docs, it seems you have externals set up incorrectly. You need your externals object set up like this: externals: { lodash: { root: '_' } }.I don't think you really have a dependency called root that you want to be exposed as _ :p Commented Dec 7, 2018 at 18:07
  • Another tip, if you're building a library that will be installed in another environment that includes lodash, ensure lodash is listed under peerDependencies in your package.json. Commented Dec 7, 2018 at 18:10
  • @chipit24 You mean the package.json of the environment? Because I don't package the component, it's just a simple script file that I include in an html file which registers itself as a Vue component. Commented Dec 7, 2018 at 18:18
  • No, I mean the package.json of your library: docs.npmjs.com/files/package.json.html#peerdependencies, yarnpkg.com/lang/en/docs/dependency-types/#toc-peerdependencies. Since you're not installing your package via npm, yarn, .etc. then it technically won't make a difference. Commented Dec 7, 2018 at 20:46
  • I don't publish a package. It's just a simple Javascript source as I've explained. Commented Dec 8, 2018 at 9:58

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the answer @tony19. This was one of the methods I tried and it works but there are libraries that don't register themselves to the window like lodash does. So in the host application I register all of them manually to the window and it works this way.
Ok. What's an example of a library that doesn't attach to window? There's likely a different config required for that library.
Our own libraries which come from our own npm packages :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.