My team has recently started moving our websites over to vue.js. On the whole everything has gone really well, but we are having problems sharing common javascript files and vue components between the different websites. I posted a question about this a while ago and we settled on keeping all the shared files in a separate repo and using a git submodule to insert the files into the projects. For a variety of reasons, we want to move away from this and my project manager has asked me to look at alternatives, but I am really struggling.

What we want to do is have all the files included alongside the projects and import them in when needed. So the file layout will just be

├── ourSharedStuff
│   ├── usefulFunctions.js
│   └── coolwidget.vue
├── website1
│   └── package.json
└── website2
    └── package.json

Then we thought to just import the files we need like so

import { somefunction } from '../ourSharedStuff/usefulFunctions';
import { coolWidget } from '../ourSharedStuff/coolwidget.vue';

However, because the import is coming from outside the project it seems to confuse webpack when it tries to resolve dependencies for anything coming from the shared project (e.g. if coolwidget.vue needed momentjs). This issue is what led to us using submodules in the first place.

Since that seemed to cause problem I thought "Ah, maybe if it is trying to resolve dependencies on the shared project from there, it should have its own dependencies declared in a package.json". So I tried adding a package.json to the shared project, and using an npm install ../ourSharedStuff/ to include it in the project. But that didn't really work either, and I still had similar problems, because when you use npm to install a file location like that, it just creates a symlink, and webpack seemed to still get confused.

After some googling it turned out that if you use npm to install a tarball then it works properly and creates the actual files in node_modules. That worked great except for one problem...files in the shared project are written in es6 and need to be transpiled. Because like nearly everyone, we exclude node_modules from being run through babel:

test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
    presets: ['@babel/preset-env'],
    plugins: [

So next I figured "Well, that exclude is just a regex, I'll just change it to exclude all the folders except ours". So I changed it to: /node_modules\/(?!ourSharedStuff)/

And webpack started giving esoteric messages when I try and build

WARNING in ./node_modules/core-js/modules/_is-object.js 4:9-16 "export 'default' (imported as '_typeof') was not found in '@babel/runtime/helpers/typeof'

I'm at a complete loss on how to achieve something that should be fairly easy. So after all that my question is: What is the best way of having shared .js and .vue files, that are written in es6 and may have external dependencies of their own, shared between multiple projects such that the necessary transforms are applied when you build those projects?

0 Answers