0

我有一个rollup.config.js看起来像这样:

import common from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
import resolve from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript';
import { babel } from '@rollup/plugin-babel';
import svgr from '@svgr/rollup';
import { terser } from 'rollup-plugin-terser';
import { join } from 'path';
import { visualizer } from 'rollup-plugin-visualizer';

const rootDir = join(__dirname, '..', '..');
const configDir = join(rootDir, 'config');
const bundleCoverageDir = join(rootDir, 'coverage', 'bundle');
const distDir = join(rootDir, 'dist');
const tsconfig = join(configDir, 'typescript', 'tsconfig.prod.json');
const environment = process.env.NODE_ENV;
const isDevelopment = environment === 'development';
const openVisualization = process.env.OPEN_VISUALIZATION === 'true';

const sharedvisualizerConfig = {
  brotliSize: true,
  gzipSize: true,
  json: false,
  open: openVisualization,
  projectRoot: rootDir,
  sourcemap: false,
  template: 'sunburst', // sunburst, treemap, network
  title: 'Rollup Bundle Visualizer'
};

const commonPlugins = [
  resolve({
    browser: true
  }),
  common({
    include: 'node_modules/**'
  }),
  replace({
    'process.env.NODE_ENV': JSON.stringify(environment),
    preventAssignment: true
  }),
  babel({
    babelHelpers: 'runtime',
    root: join(configDir, 'babel')
  }),
  svgr(),
  !isDevelopment &&
    terser({
      compress: true,
      format: {
        comments: 'some'
      }
    })
];

function createBundleConfig({ fileName, bundleType, plugins }) {
  return {
    output: [
      {
        file: join(distDir, 'components', `${fileName}.${bundleType}.min.js`),
        format: bundleType,
        extend: true
      }
    ],
    plugins: [
      ...plugins,
      visualizer({
        ...sharedvisualizerConfig,
        filename: join(bundleCoverageDir, `bundle-report-${bundleType}.html`)
      })
    ]
  };
}

export default commandLineArgs => {
  const fileName = commandLineArgs.name || 'output';

  const ESM = createBundleConfig({
    fileName,
    bundleType: 'esm',
    plugins: [...commonPlugins, typescript({ target: 'es6', tsconfig })]
  });

  const UMD = createBundleConfig({
    fileName,
    bundleType: 'umd',
    plugins: [...commonPlugins, typescript({ target: 'es5', tsconfig })]
  });

  return [ESM, UMD];
};

join注意:调用中的所有路径等都是正确且经过验证的。

使用以下命令运行捆绑器以进行生产:

cross-env NODE_ENV=production rollup -c config/rollup/rollup.config.js -i src/App.tsx -n components

在我的项目rollup版本2.64.0中正在使用。插件版本是:

...
    "@rollup/plugin-babel": "^5.3.0",
    "@rollup/plugin-commonjs": "^21.0.1",
    "@rollup/plugin-node-resolve": "^13.1.3",
    "@rollup/plugin-replace": "^3.0.1",
    "@rollup/plugin-typescript": "^8.3.0",
    "@svgr/rollup": "^6.2.0",
    "rollup-plugin-terser": "^7.0.2",
    "rollup-plugin-visualizer": "^5.5.4"
...

一个组件的示例,当然是简化的,是:

import React, { FC, useState, MouseEvent } from 'react';

import { DownIcon, UpIcon } from 'shared/icons';
import { theme } from 'shared/theme';
import { pixelToRem } from 'shared/utils/pixelToRem';

export type AccordionProps = {
  header: string | React.ReactElement;
  isExpanded?: boolean;
  dataTestId?: string;
} & React.DetailsHTMLAttributes<HTMLElement>;

export const Accordion: FC<AccordionProps> = ({
  header,
  isExpanded = true,
  dataTestId: testId,
  children
}) => {
  const [expanded, setExpanded] = useState(!!isExpanded);

  const onToggle = (event: MouseEvent<HTMLElement, globalThis.MouseEvent>) => {
    event.preventDefault();
    setExpanded(!expanded);
  };

  return (
    <>
      <details className="Accordion" open={expanded} data-testid={testId}>
        <summary onClick={onToggle} className="Accordion__summary">
          {header}
          {expanded ? <UpIcon /> : <DownIcon />}
        </summary>

        {children}
      </details>

      <style jsx>{`
        .Accordion {
          background: ${theme.colors.white01};
          padding-bottom: ${pixelToRem(12)};
          border-bottom: ${pixelToRem(1)} solid ${theme.colors.grey05};
        }

        .Accordion__summary {
          cursor: pointer;
          display: flex;
          justify-content: space-between;
          align-items: center;
          min-height: ${pixelToRem(48)};
          font-size: ${theme.fonts.size.subline};
          color: ${theme.colors.black01};
          user-select: none;
        }

        .Accordion__summary :global(svg) {
          width: ${pixelToRem(24)};
          height: ${pixelToRem(24)};
        }
      `}</style>
    </>
  );
};

babel.config.js看起来像这样:

module.exports = {
  presets: [
    '@babel/env',
    ['@babel/react', { runtime: 'automatic' }],
    '@babel/preset-typescript'
  ],
  plugins: [
    'styled-jsx/babel',
    '@babel/plugin-transform-runtime'
  ]
};

在使用 Storybook 进行本地开发时,一切都按预期呈现,没有问题,并且使用相同的 babel 配置!

但是,当我在开发或生产模式下运行汇总时,它会成功编译,但是当我通过捆绑呈现组件客户端时,它会抱怨styled-jsx不包括在内。我还可以在构建中看到:global伪类在构建过程中也没有被正确地转译,但 babel 似乎肯定是在构建过程中运行的,等等,它使用styled-jsx/babel插件,如上所示......

我已经尝试了所有我能想到的东西,例如:我查看了插件的顺序,浏览了styled-jsx每个汇总插件的文档和问题,等等,但我无法弄清楚为什么它会毫无错误地捆绑在一起,但是,它是一个无效的构建!

我发现打算将其捆绑项目用作 npm 依赖项的文章,他们希望将其styled-jsx用作对等依赖项,但对于此项目,它必须包含在捆绑包中,因为构建仅适用于非节点环境中的客户端 JavaScript 捆绑包因此,对等依赖项等不是一种选择,它必须在构建时构建和运行。

如果有人有任何想法或需要我的进一步澄清,我非常乐意提供背景信息或回答任何问题,请务必让我知道。否则,我会很高兴获得有关如何正确捆绑和运行的任何提示。

4

0 回答 0