Vue-cli with monorepo has duplicate modules

vue-cli

#1

I’m using vue-cli --target lib to build a component and include it in another project within a monorepo. Some node_modules exist twice in the final app bundle. These are the emitted reports: https://gist.github.com/johannes-z/662b85f4429919c1e716f3928a11840b

The .common.js file is the --target lib build.

Edit: If I put "main": "src/main.ts" in the component’s package.json the vendor bundle seems to be correct, but that can’t be right?


#2

That’s very little info to work with.

Are those bundled packages actually used in both the linked plugin and the consuming app?

Have you properly excluded them from bundling in the plugin package config by making them externals in the webpack config?


#3

Hi sorry, what other information do you need?

I build the property-pane package with this command:

"build": "vue-cli-service build --target lib --name property-pane ./src/main.ts --report",

Other than that it’s a barebone vue-cli typescript project without a vue.config.js. I thought --target lib would take care of excluding vue from the build (which it seems it does). But the other dependency office-ui-fabric-vue is not extracted properly. It’s the same import name, so shouldn’t webpack automatically only include 1 copy of the library in the bundle?


#4

No, because in your plugin, you bundled that other dependency into the output. After that, the second webpack run in your app won’t be able to match its local copy of tat dependency with the bundled version in your plugin.

That’s what webpack’s “externals” option is for: telling webpack to not bundle some dependencys, so they will be injected into your plugin when the second webpack run bundles the app.


#5

So I would have to do something like this?

module.exports = {
  configureWebpack: {
    externals: [
      'vue',
      '@johannes-z/office-ui-fabric-vue',
    ],
  },
}

What about core-js polyfills? Is there a better way to do this than add all externals manually? Because what would happen, if the consuming app didn’t bundle @johannes-z/office-ui-fabric-vue for example? Then it wouldn’t be in the final bundle at all, right?


#6

disable useBuiltIns in the babel config, which will skip adding of polyfills.

Make sure to document which polyfills users might have to add.

You can import package.json into your vue.config.js and add all keys of the dependencies object to externals.

Since @johannes-z/office-ui-fabric-vue is listed as a dependency in your plugin’s package.json's dependencies field, it will be installed as a transitive dependency when the consuming app installs your plugin.

So it will be present in node_modules and webpack will be able to inject it into your plugin during bundling.