Sharing TypeScript code between Node.js and Vue.js

Viewed 284

I'm having a hard time figuring out how to do this. My environment is:

  • Node.js 16.1.x
  • Vue.js 3.x
  • TypeScript 4.2.4

My directory structure is like this:

  • Root (Node.js server)
    • shared
      • MySharedFile.ts
    • ui (Vue.js code)

MySharedFile.ts is exporting a very simple module:

export const MyShared = {
  TEST: 1
};

In Vue.js, I'm trying to import this module import {MyShared} from '../../shared/MySharedFile', but when the app builds, I get the error Parsing error: 'import' and 'export' may appear only with 'sourceType: module'. I've searched and found a thread that suggests changing the eslintrc settings, which didn't work. This error really doesn't make sense to me, so what does it mean, and how can I fix it?

ui/tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "outDir": "./dist",
    // https://github.com/TypeStrong/ts-loader/issues/1138
    "importsNotUsedAsValues": "preserve",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "es2020",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

ui/.eslintrc.js

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    '@vue/typescript',
    'plugin:vue/vue3-recommended',
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/typescript/recommended'
  ],
  parserOptions: {
    ecmaVersion: 11,
    sourceType: 'module',
    allowImportExportEverywhere: true
  }
}

For anyone wanting the source code... I'm now at a new error Parsing error: ‘import’ and ‘export’ may appear only with ‘sourceType: module’

1 Answers

I learned a few things with this. The first is that I'm using what's referred to as a monorepo. The second was that I should be using some sort of workspace, and I ended up using npm workspaces, but there're other options, like yarn workspaces. I had to refactor my app to follow a different structure, so I now have something like this:

  • Root (main workspace)
    • api (Node.js)
      • package.json ("dependencies": {"shared": "^1.0.0"})
      • tsconfig.json
      • package-lock.json (removed this)
    • shared (TypeScript code)
      • package.json ("version": "1.0.0")
      • tsconfig.json
    • ui (Vue.js)
      • package.json ("dependencies": {"shared": "^1.0.0"})
      • tsconfig.json
      • package-lock.json (removed this)
    • package.json ("workspaces": ["api", "shared", "ui"])
    • package-lock.json (this gets generated and now contains all deps for workspaces)

After moving to this structure, I didn't have to modify the tsconfig.json or vue.config.js files to add the shared dir, as I could reference it like any other package when importing. I also like this approach because it keeps all of my node_modules in one dir at the main workspace level.

Related