Vue + Typescript + rollup

6.1k views Asked by At

I'm trying to rollup Vue component lib, written on the typescript + vue-property-decorator. I have several Vue components, and plugin class in a separated file, where the components are imported:

import FormularioForm from '@/FormularioForm.vue'
import FormularioInput from '@/FormularioInput.vue'
import FormularioGrouping from '@/FormularioGrouping.vue'

The test suite (vue-cli + jest) working fine, all tests passing, but on the build stage with rollup module path resolution working incorrect, since the code of the components not present in the final build.

rollup.config:

import autoExternal from 'rollup-plugin-auto-external'
import buble from '@rollup/plugin-buble'
import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import typescript from '@rollup/plugin-typescript'
import vue from 'rollup-plugin-vue'

export default {
    input: 'src/index.ts',
    output: [{
        name: 'Formulario',
        exports: 'default',
        globals: {
            'is-plain-object': 'isPlainObject',
            'is-url': 'isUrl',
            'nanoid/non-secure': 'nanoid',
        },
        sourcemap: false,
    }],
    external: ['nanoid/non-secure'],
    plugins: [
        commonjs(),
        autoExternal(),
        typescript({ sourceMap: false }),
        vue({
            css: true,
            compileTemplate: true
        }),
        buble({
            objectAssign: 'Object.assign',
        }),
        terser(),
    ]
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.js",
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

package.json

{
    "name": "@retailcrm/vue-formulario",
    "version": "0.1.0",
    "author": "RetailDriverLLC <[email protected]>",
    "scripts": {
        "build": "npm run build:esm & npm run build:umd & npm run build:iife & wait && echo \"Build complete:\nesm: $(gzip -c dist/formulario.esm.js | wc -c)b gzip\numd: $(gzip -c dist/formulario.umd.js | wc -c)b gzip\nmin: $(gzip -c dist/formulario.min.js | wc -c)b gzip\"",
        "test": "NODE_ENV=test jest --config test/jest.conf.js",
        "build:esm": "rollup --config build/rollup.config.js --format es --file dist/formulario.esm.js",
        "build:iife": "rollup --config build/rollup.iife.config.js --format iife --file dist/formulario.min.js",
        "build:size": "gzip -c dist/formulario.esm.js | wc -c",
        "build:umd": "rollup --config build/rollup.config.js --format umd --file dist/formulario.umd.js",
        "dev": "vue-cli-service serve --port=7872 examples/main.js",
        "test:coverage": "NODE_ENV=test jest --config test/jest.conf.js --coverage",
        "test:watch": "NODE_ENV=test jest --config test/jest.conf.js --watch"
    },
    "main": "dist/formulario.umd.js",
    "module": "dist/formulario.esm.js",
    "browser": {
        "./sfc": "src/index.ts"
    },
    "unpkg": "dist/formulario.min.js",
    "dependencies": {
        "is-plain-object": "^3.0.0",
        "is-url": "^1.2.4",
        "nanoid": "^2.1.11",
        "vue-class-component": "^7.2.3",
        "vue-i18n": "^8.17.7",
        "vue-property-decorator": "^8.4.2"
    },
    "devDependencies": {
        "@babel/core": "^7.9.6",
        "@babel/plugin-transform-modules-commonjs": "^7.9.6",
        "@babel/preset-env": "^7.9.6",
        "@rollup/plugin-alias": "^3.1.1",
        "@rollup/plugin-buble": "^0.21.3",
        "@rollup/plugin-commonjs": "^11.1.0",
        "@rollup/plugin-node-resolve": "^7.1.3",
        "@rollup/plugin-typescript": "^6.0.0",
        "@types/is-url": "^1.2.28",
        "@types/jest": "^26.0.14",
        "@types/nanoid": "^2.1.0",
        "@typescript-eslint/eslint-plugin": "^2.26.0",
        "@typescript-eslint/parser": "^2.26.0",
        "@vue/cli-plugin-babel": "^4.3.1",
        "@vue/cli-plugin-eslint": "^4.3.1",
        "@vue/cli-plugin-typescript": "^4.5.7",
        "@vue/cli-service": "^4.5.4",
        "@vue/component-compiler-utils": "^3.1.2",
        "@vue/eslint-config-standard": "^5.1.2",
        "@vue/eslint-config-typescript": "^5.0.2",
        "@vue/test-utils": "^1.0.2",
        "autoprefixer": "^9.7.6",
        "babel-core": "^7.0.0-bridge.0",
        "babel-eslint": "^10.1.0",
        "babel-jest": "^25.5.1",
        "eslint": "^5.16.0",
        "eslint-config-standard": "^12.0.0",
        "eslint-plugin-import": "^2.20.1",
        "eslint-plugin-node": "^8.0.1",
        "eslint-plugin-promise": "^4.1.1",
        "eslint-plugin-standard": "^4.0.0",
        "eslint-plugin-vue": "^5.2.3",
        "flush-promises": "^1.0.2",
        "jest": "^26.5.2",
        "jest-vue-preprocessor": "^1.7.1",
        "rollup": "^1.32.1",
        "rollup-plugin-auto-external": "^2.0.0",
        "rollup-plugin-internal": "^1.0.4",
        "rollup-plugin-multi-input": "^1.1.1",
        "rollup-plugin-terser": "^5.3.0",
        "rollup-plugin-vue": "^5.1.7",
        "ts-jest": "^26.4.1",
        "typescript": "~3.9.3",
        "vue": "^2.6.11",
        "vue-jest": "^3.0.5",
        "vue-runtime-helpers": "^1.1.2",
        "vue-template-compiler": "^2.6.11",
        "vue-template-es2015-compiler": "^1.9.1",
        "watch": "^1.0.2"
    },
    "bugs": {
        "url": "https://github.com/retailcrm/vue-formulario/issues"
    },
    "contributors": [
        "Justin Schroeder <[email protected]>"
    ],
    "keywords": [
        "vue",
        "form",
        "forms",
        "validation",
        "validate"
    ],
    "license": "MIT",
    "publishConfig": {
        "access": "public"
    },
    "repository": {
        "type": "git",
        "url": "git+ssh://[email protected]/retailcrm/vue-formulario.git"
    }
}

Caught on the console:

(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
@/FormularioForm.vue (imported by src/Formulario.ts)
@/FormularioInput.vue (imported by src/Formulario.ts)
@/FormularioGrouping.vue (imported by src/Formulario.ts)

Trying to find out an appropriate solution.

Full code placed here: https://github.com/cmath10/vue-formulario

1

There are 1 answers

2
Estus Flask On BEST ANSWER

That tsconfig contains paths affects only how TypeScript compiler resolves modules but doesn't replace aliased import paths in JS output. It's possible for tools to transparently process files with a respect to paths option but this shouldn't be expected.

Module aliasing for the bundle can be addressed by another Rollup plugin like @rollup/plugin-alias. This reveals the problem with the latest @rollup/plugin-typescript that results in processing errors when it's used with other plugins.

A way to make this setup workable is to switch to another TypeScript plugin, rollup-plugin-typescript2:

import alias from '@rollup/plugin-alias';
import typescript from 'rollup-plugin-typescript2'    
...
plugins: [
    typescript({
         check: false // disable typechecks if necessary
    }),
    vue({ css: true, compileTemplate: true }),
    alias({ entries: [{ find:/^@\/(.+)/, replacement: './$1' }] }),
    commonjs(),
    autoExternal(),
    buble({ objectAssign: 'Object.assign' }),
    terser(),
]

There may be no need for Buble plugin because TypeScript is able to handle ES5 transpilation.