首页 > 解决方案 > Rollup + Typescript:最终输出中的 lib/index.js 连接模块

问题描述

我正在为我们在 NPM 上发布的库创建构建过程。我们正在从 webpack 迁移到 rollup 以支持 treeshaking 和 ESM。

我们面临的问题是,当我们分析最终捆绑包时,我可以准确地看到我们从 node_modules 导入的内容,而对于主 index.js 和我们自己的组件/文件,我看不到相同的内容

如果我只使用打字稿编译库,则输出如下: TSC 编译输出

tsconfig.json

{
  "include": ["src"],
  "exclude": [
    "lib",
    "**/*.stories.tsx",
    "**/*.stories.ts",
    "**/*.test.ts",
    "**/*.test.tsx",
    "**/__mocks__/*",
    "node_modules"
  ],
  "compilerOptions": {
    "noImplicitAny": false,
    "noImplicitReturns": false,
    "noImplicitThis": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "target": "es5",
    "module": "ESNext",
    "moduleResolution": "node",
    "lib": ["es6", "dom", "es2016", "es2017"],
    "sourceMap": true,
    "declaration": true,
    "allowSyntheticDefaultImports": true,
    "outDir": "lib",
    "jsx": "react",
    "allowJs": false,
    "suppressImplicitAnyIndexErrors": true,
    "esModuleInterop": true
  }
}

如果我使用汇总构建,这是输出:

汇总结果

rollup.config.js

import pkg from './package.json';
import typescript from 'rollup-plugin-typescript2';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import external from 'rollup-plugin-peer-deps-external';
import { terser } from 'rollup-plugin-terser';

/**
 * Config tweaked from: https://www.pluralsight.com/guides/react-typescript-module-create
 */

export default {
  input: 'src/index.ts',
  output: [
    { file: pkg.main, format: 'cjs', sourcemap: true, exports: 'named' },
    { file: pkg.module, format: 'es', sourcemap: true, exports: 'named' },
  ],
  plugins: [
    external(), // prevents from bundling peer dependencies
    resolve(), // bundles third party dependencies we've installed in node_modules.
    typescript({
      rollupCommonJSResolveHack: true,
      clean: true,
    }),
    commonjs({
      // compiles js files into commonjs
      include: /node_modules/,
      namedExports: {
        'node_modules/react/react.js': ['Children', 'Component', 'PropTypes', 'createElement'],
        'node_modules/react-dom/index.js': ['render'],
        'node_modules/react-dates/index.js': [
          'DayPickerRangeController',
          'CalendarInfoPositionShape',
          'DateRangePicker',
          'SingleDatePicker',
        ],
        'node_modules/xss/lib/index.js': ['DEFAULT', 'whiteList'],
        'node_modules/uuid/index.js': ['v4'],
      },
    }),
    terser(), // uglify and minification of bundle
  ],
};

我希望能够实现第一个结果(使用 TSC 编译器的结果),在该结果中我可以保持库项目结构,但使用汇总构建过程来利用 treeshaking 和缩小过程。

我的配置中缺少什么?

标签: javascripttypescriptbundlerolluprollupjs

解决方案


您可以尝试通过以下代码替换您的插件文件:

      nodeResolve({
        browser: true,
        dedup: ['react', 'react-dom'],
        extensions,
      }),
      postcss({
        extract: join(outputDir, 'index.css'),
        modules: {
          generateScopedName: cssScopeName,
        },
        namedExports: cssExportName,
        plugins: [
          postcssImport(),
        ],
      }),
      typescript({
        allowNonTsExtensions: true,
        useTsconfigDeclarationDir: true,
        objectHashIgnoreUnknownHack: true,
        tsconfigDefaults: {
          compilerOptions: {
            baseUrl: sourceDir,
            target: 'esnext',
            jsx: 'preserve',
            emitDecoratorMetadata: true,
            allowSyntheticDefaultImports: true,
            experimentalDecorators: true,
            paths: {
              [[pkg.name, "*"].join("/")]: [join(outputDir, pkg.name, "*")]
            }
            },
          }
      }),
      commonjs({
        include: [resolve(rootPath, 'node_modules/**')],
        exclude: [resolve(rootPath, 'node_modules/process-es6/**')],
        namedExports:{
          [resolve(rootPath, 'node_modules/react/index.js')]: [
            "Children",
            "Component",
            "PropTypes",
            "createRef",
            "useEffect",
            "useState",
            "useContext",
            "useRef",          ],
          [resolve(rootPath, "node_modules/react-dom/index.js")]: ["render", "findDOMNode"],
          [resolve(rootPath, "node_modules/react-is/index.js")]: ["isValidElementType"]
        },
      }),
      babel({
        babelrc: false,
        extensions,
        presets: [
          [ '@babel/preset-env', { modules: false } ],
          [ '@babel/preset-react' ],
        ],
      }),
......

推荐阅读