最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to get rollup to include a dependency from another package in a lerna monorepo in its transpilation (TypeScript

programmeradmin1浏览0评论

I created a minimal example to show the question I have: Github repo.

I have a lerna monorepo with two npm packages in the packages folder, the packages are called:

utils: exports a function:

export const add = (a:number, b: number) => a + b

component-library:: exports one simple functional React component:

import React from 'react';
import { add } from '@project/utils';

export const MyComponent = () => <div>{add(2, 2)}</div>;

The root of the monorepo has a tsconfig.json, which defines a paths key to map any imports of the form @project/* to the packages.

{
  "compilerOptions": {
    "jsx": "react",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node",
    "allowJs": true,
    "baseUrl": ".",
    "paths": {
      "@project/*": ["packages/*/src"]
    }
  },
  "exclude": ["**/build/**"]
}

Each package has a rollup.config.js, both essentially identical (though we're only going to use the one in the component-library package here):

import typescript from '@rollup/plugin-typescript';
import commonjs from '@rollup/plugin-commonjs';

export default {
    input: 'src/index.tsx',
    output: {
        dir: './build',
        format: 'cjs'
    },
    plugins: [
        commonjs(),
        typescript({ tsconfig: '../../tsconfig.json'}),
    ]
};

Therefore, they both use the paths defined in the root tsconfig.json, and they use a plugin for transpiling Typescript.

component-library imports a function from @project/utils called add(a,b).

My goal is to create a build of this library (using rollup), without having to build the utils package first. In other words, I want to build component-library resolving imports from utils to the source code of utils, not the build folder in the symlinked package in node_modules (ie, not using the symlinks created by lerna).

I almost achieve this, except that when I run the build script in component-library, I get an error:

src/index.tsx → ./build... [!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript) ..\utils\src\index.ts (1:21) 1: export const add = (a:number, b: number) => a + b ^

The way I understand this, it means that the resolution of the import works fine, but rollup is not transpiling the TS file coming from an external dependency.

How do I tell rollup to include the file from utils in the transpilation through rollup?

I created a minimal example to show the question I have: Github repo.

I have a lerna monorepo with two npm packages in the packages folder, the packages are called:

utils: exports a function:

export const add = (a:number, b: number) => a + b

component-library:: exports one simple functional React component:

import React from 'react';
import { add } from '@project/utils';

export const MyComponent = () => <div>{add(2, 2)}</div>;

The root of the monorepo has a tsconfig.json, which defines a paths key to map any imports of the form @project/* to the packages.

{
  "compilerOptions": {
    "jsx": "react",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node",
    "allowJs": true,
    "baseUrl": ".",
    "paths": {
      "@project/*": ["packages/*/src"]
    }
  },
  "exclude": ["**/build/**"]
}

Each package has a rollup.config.js, both essentially identical (though we're only going to use the one in the component-library package here):

import typescript from '@rollup/plugin-typescript';
import commonjs from '@rollup/plugin-commonjs';

export default {
    input: 'src/index.tsx',
    output: {
        dir: './build',
        format: 'cjs'
    },
    plugins: [
        commonjs(),
        typescript({ tsconfig: '../../tsconfig.json'}),
    ]
};

Therefore, they both use the paths defined in the root tsconfig.json, and they use a plugin for transpiling Typescript.

component-library imports a function from @project/utils called add(a,b).

My goal is to create a build of this library (using rollup), without having to build the utils package first. In other words, I want to build component-library resolving imports from utils to the source code of utils, not the build folder in the symlinked package in node_modules (ie, not using the symlinks created by lerna).

I almost achieve this, except that when I run the build script in component-library, I get an error:

src/index.tsx → ./build... [!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript) ..\utils\src\index.ts (1:21) 1: export const add = (a:number, b: number) => a + b ^

The way I understand this, it means that the resolution of the import works fine, but rollup is not transpiling the TS file coming from an external dependency.

How do I tell rollup to include the file from utils in the transpilation through rollup?

Share Improve this question asked Mar 17, 2020 at 19:45 xouxxoux 3,4943 gold badges31 silver badges59 bronze badges 6
  • 3 Hey, did you ever figure this out? – Shawn Mclean Commented Jul 22, 2020 at 16:01
  • Similar stackoverflow.com/questions/66784292/… – Fred Hors Commented Mar 24, 2021 at 15:42
  • Did you fix this @evianpring? – Fred Hors Commented Mar 24, 2021 at 15:43
  • A small thing, but looking at your Rollup setup and comparing to mine, there's one thing missing. I put nodeResolve({ extensions, }), first, inside plugins[], above commonjs(),. The extensions is a string array like const extensions = [".js", ".json", ".node", ".ts", ".tsx"];. Try this. The import is import { nodeResolve } from "@rollup/plugin-node-resolve";. – revelt Commented Apr 2, 2021 at 19:02
  • @xoux did you find a solution to this? – Gary Commented Sep 22, 2024 at 20:22
 |  Show 1 more comment

4 Answers 4

Reset to default 0

If this is really the issue

The way I understand this, it means that the resolution of the import works fine, but rollup is not transpiling the TS file coming from an external dependency.

You can run Babel from @rollup/plugin-babel and transpile ts files with Babel directly. Babel will go over files in node_modules.

I have the project (lerna + rollup) and make the following settings for typing:

  • my rollup config looks like this

import {defineConfig} from 'rollup';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import {terser} from 'rollup-plugin-terser';
import url from '@rollup/plugin-url';

import * as fs from 'fs';
import path from 'path';

const PACKAGE_NAME = process.cwd();
const packageJson = JSON.parse(fs.readFileSync(path.join(PACKAGE_NAME, 'package.json'), 'utf-8'));

const includePaths = ['**/*.woff', '**/*.woff2', '**/*.svg', '**/*.png'];

export default defineConfig({
  input: 'src/index.ts',
  output: [
    {
      file: packageJson.main,
      format: 'cjs',
      sourcemap: false,
      name: packageJson.name,
    },
    {
      file: packageJson.module,
      format: 'es',
      sourcemap: false,
      name: packageJson.name,
    },
  ],
  plugins: [
    resolve(),
    commonjs(),
    typescript({tsconfig: './tsconfig.json'}),
    terser(),
    url({
      fileName: '[name][extname]',
      include: includePaths,
      limit: 0,
    }),
  ],
  external: [...Object.keys(packageJson.peerDependencies || {})],
});```

  • the tsconfig.json looks like this

{
  "compilerOptions": {
    "baseUrl": "src",
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "outDir": "dist",
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "downlevelIteration": true,
    "jsx": "react-jsx",
    "noFallthroughCasesInSwitch": true,
    "declaration": true,
    "declarationDir": ".",
    "emitDeclarationOnly": true
  },
  "include": ["rollup.config.ts"],
  "exclude": ["node_modules", "dist", "src/**/*.test.tsx", "src/**/*.stories.tsx"]
}

It is also important to add settings (module, exports, types) for types in the package.json file, for example settings for some npm package:

{
  "name": "@portfolio-yues-it-npm/icons",
  "main": "./dist/cjs/index.js",
  "module": "./dist/es/index.js",
  "exports": {
    "types": "./dist/es/index.d.ts",
    "import": "./dist/es/index.js",
    "default": "./dist/cjs/index.js"
  },
  "types": "./dist/es/index.d.ts",
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "rollup --config ../../rollup.config.ts --configPlugin @rollup/plugin-typescript"
  },
  "devDependencies": {
    ...
  }
}

P.S. Maybe this will help you, I wrote an article about lerna + rollup settings

For a monorepo, many if not all packages will be hoisted. So get the resolving to look higher. Try using the nodeResolve option:

{
    rootDir: path.join(process.cwd(), '..')
}

I was able to build a working monorepo like the on you described using @rollup/plugin-node-resolve and rollup-plugin-typescript2. The component library just serves out react components which can be installed with npm. I got it working using esm as the output type and omitting the commonjs() step in plugins.

The plugins section looks something like this:

plugins: [
  resolve(),
  typescript({ tsconfig: "./tsconfig.json" }),
],

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论