Skip to content

转译器:SWC

¥Transpiler: SWC

信息

从 Meteor 3.3 开始

¥Starting with Meteor 3.3

转译器会将所有应用代码中的现代 JS 语法转换为跨浏览器兼容的版本。

¥The transpiler converts modern JS syntax in all app code to a cross-browser compatible version.

Meteor 长期以来一直使用 Babel,这是一款成熟且至今仍被广泛采用的转译器。但是,它在速度方面落后于 SWC 等较新的工具。SWC 和其他软件包不仅速度更快,而且使用率和功能也在不断增长,已达到与 Babel 相当的水平。

¥Meteor has long used Babel, a mature and still widely adopted transpiler. However, it lags behind newer tools like SWC in terms of speed. SWC and others are not only faster but are growing in use and features, reaching parity with Babel.

由于转译是开发过程中最慢的步骤之一,Meteor 现在允许你选择在应用中使用 SWC。

¥Since transpilation is one of the slowest steps in development, Meteor now gives you the option to use SWC for your apps.

启用 SWC

¥Enable SWC

将此添加到你应用的 package.json

¥Add this to your app's package.json:

json
"meteor": {
  "modern": true
}

启动 Web 或原生应用时,SWC 将处理所有文件:你的应用、npm 软件包和 Atmosphere 软件包。这也适用于生产构建。

¥When starting your app for web or native, SWC will handle all files: your app, npm packages, and Atmosphere packages. This also applies to production builds.

默认情况下,"modern": true 启用所有构建堆栈升级。要退出 SWC 转译器,请在你的 package.json 中设置 "transpiler": false

¥By default, "modern": true enables all build stack upgrades. To opt out of SWC transpiler, set "transpiler": false in your package.json.

json
"meteor": {
  "modern": {
    "transpiler": false
  }
}

详细的转译过程

¥Verbose transpilation process

要分析和改进转译,你可以启用详细输出。将此添加到 package.json

¥To analyze and improve transpilation, you can enable verbose output. Add this to package.json:

json
"meteor": {
  "modern": {
    "transpiler": {
      "verbose": true
    }
  }
}

这会显示每个正在处理的文件、其上下文、缓存使用情况以及是否由于不兼容而回退到 Babel。

¥This shows each file being processed, its context, cache usage, and whether it fell back to Babel due to incompatibilities.

调整你的代码以从 SWC 中受益

¥Adapt your code to benefit from SWC

如果你的所有代码都使用 SWC,那么你可以关闭详细功能。但如果你使用 查看类似日志

¥If all your code uses SWC, you're good and can turn off verbosity. But if you see logs like:

shell
[Transpiler] Used Babel for <file>     (<context>)     Fallback
  <more-details>

这意味着 SWC 遇到了文件的语法不兼容问题。你可以执行以下几项操作。

¥This means SWC encountered syntax incompatibilities on the files. There are a few things you can do.

首先,检查回退详细信息以修复语法。这或许可以解释 SWC 失败的原因。

¥First, check the fallback details to fix the syntax. They might explain why SWC failed.

  • 常见原因是 函数内嵌套导入语句。将它们移至顶层。这些功能在 Babel 中有效,是因为 Meteor 有一个特定的插件,而 SWC 不支持该插件。

    ¥A common cause is nested import statements inside functions. Move them to the top level. These work in Babel due to a Meteor-specific plugin, which SWC doesn’t support.

  • 其他问题可能来自与 Babel 插件相关的功能。你需要查找 SWC 等效版本。查看 SWC 插件列表

    ¥Other issues may come from features tied to Babel plugins. You’ll need to find SWC equivalents. See the SWC plugin list.

其次,如果这些文件在 Babel 中运行良好,则忽略回退。SWC 仍会加速其他文件。Meteor 在未来版本中将继续使用 Babel 处理不兼容的文件。

¥Second, ignore the fallback if those files run fine with Babel. SWC will still speed up other files. Meteor will keep using Babel for incompatible files on future builds.

第三,从 SWC 中排除文件或上下文。即使它会自动回退,你也可以避免在已知不兼容的文件上尝试 SWC 的开销。

¥Third, exclude files or contexts from SWC. Even though it falls back automatically, you can skip the overhead of trying SWC on known-incompatible files.

例如,如果你正在使用 babel-plugin-react-compiler,其中包含 SWC 尚不支持,则可以将以下内容添加到 package.json 中以排除你的应用代码:

¥For example, if you're using babel-plugin-react-compiler, which SWC doesn't support yet, you can exclude your app code adding this to package.json:

json
"meteor": {
  "modern": {
    "transpiler": {
      "excludeApp": true
    }
  }
}

或者仅排除特定文件,例如 .jsx

¥Or exclude only specific files like .jsx:

json
"meteor": {
  "modern": {
    "transpiler": {
      "excludeApp": ["\\.jsx"]
    }
  }
}

你还可以使用 excludePackagesexcludeNodeModulesexcludeLegacy 进行更精细的控制。更多信息请参阅 modern.transpiler config docs

¥You can also use excludePackages, excludeNodeModules, and excludeLegacy for finer control. See the modern.transpiler config docs for more.

当不存在任何插件时,这些设置允许你通过限制回退使用来获得 SWC 的大部分速度优势。

¥When no plugin exists, these settings let you still get most of SWC’s speed benefits by limiting fallback use.

大多数应用只需启用 modern: true 即可受益。大多数 Meteor 软件包应该可以立即运行,使用嵌套导入的软件包除外。Node 模块也基本可以正常工作,因为它们遵循通用标准。大多数应用代码也应该可以运行,除非它依赖于 Babel 特定的行为。

¥Most apps will benefit just by enabling modern: true. Most Meteor packages should work right away, except ones using nested imports. Node modules will mostly work too, since they follow common standards. Most app code should also work unless it depends on Babel-specific behavior.

优化完成后,请记得关闭详细功能。

¥Remember to turn off verbosity when you're done with optimizations.

外部化 SWC 助手

¥Externalize SWC Helpers

默认情况下,SWC 会将转换辅助函数(例如 _extends、_objectSpread)内联到每个使用它们的文件中。虽然这确保了开箱即用的兼容性,但也可能导致包中出现重复代码,从而增加包的大小。

¥By default, SWC inlines transformation helpers (e.g. _extends, _objectSpread) into every file that uses them. While this ensures compatibility out of the box, it can lead to duplicated code across your bundles increasing bundle size.

为了集中管理这些辅助函数并保持客户端构建的精简,你可以将 @swc/helpers 添加到你的应用项目中。

¥To centralize these helpers and keep your client builds lean, you can add the @swc/helpers in your app project.

bash
meteor npm install --save @swc/helpers

新应用默认安装此包。

¥This package is installed by default for new apps.

Meteor 的构建工具已预先配置为外部化 SWC 辅助函数,无需额外设置或修改 .swcrc 文件。安装 @swc/helpers 后,Meteor 的 SWC 管道会自动为共享辅助函数发出导入语句,而不是内联它们,从而确保你的应用只发布每个辅助函数一次。

¥Meteor’s build tool comes pre-configured to externalize SWC helpers for you, no extra setup or .swcrc tweaks are needed. As soon as you install @swc/helpers, Meteor’s SWC pipeline will automatically emit imports for shared helper functions rather than inlining them, ensuring your app ships each helper just once.

自定义 .swcrc 文件

¥Custom .swcrc

你可以在项目根目录中使用 .swcrc 配置来描述其中的特定 SWC 插件,该配置将应用于编译项目的整个文件。

¥You can use .swcrc config in the root of your project to describe specific SWC plugins there, that will be applied to compile the entire files of your project.

你也可以使用 .swcrc 格式配置其他选项。有关自定义 SWC 配置,请参阅 SWC 配置 API

¥You can also configure other options using the .swcrc format. For custom SWC configs, see the SWC configuration API.

在项目根目录中使用 swc.config.js 进行动态配置。Meteor 将自动导入并应用 SWC 配置。这允许你根据环境变量或其他运行时因素选择配置。

¥Use swc.config.js in your project root for dynamic configuration. Meteor will import and apply the SWC config automatically. This lets you choose a config based on environment variables or other runtime factors.

你还可以查看以下使用自定义 .swcrc 配置的迁移主题:

¥You can also review these migration topics that use custom .swcrc configs:

警告

SWC 配置文件的标准名称为 .swcrc

¥The standard name for the SWC configuration file is .swcrc.

将其用作扩展名(例如 config.swcrc)将不起作用。

¥Using as an extension, such as config.swcrc, won’t work.

配置 API

¥Config API

  • modern.transpiler: [true|false] - 默认:true 启用或禁用现代转译器 (SWC)。如果禁用,将直接使用 Babel。

    ¥modern.transpiler: [true|false] - Default: true Enables or disables the use of the modern transpiler (SWC). If disabled, Babel will be used directly instead.

  • modern.transpiler.excludeApp: [true|false] or [string[]] 如果设置为 true,应用自身的代码(Meteor 核心和软件包之外的代码)将继续使用 Babel。否则,输出应用内要从 SWC 转译中排除的文件路径或类似正则表达式的模式列表。

    ¥modern.transpiler.excludeApp: [true|false] or [string[]] If true, the app’s own code (outside of Meteor core and packages) will continue using Babel. Otherwise, a list of file paths or regex-like patterns within the app to exclude from SWC transpilation.

  • modern.transpiler.excludeNodeModules: [true|false] or [string[]] 如果为 true,则应用的 node_modules 将继续使用 Babel。否则,请列出 node_modules 文件夹中的 NPM 包名称、文件路径或类似正则表达式的模式,以将其从 SWC 转译中排除。

    ¥modern.transpiler.excludeNodeModules: [true|false] or [string[]] If true, the app’s node_modules will continue using Babel. Otherwise, a list of NPM packages names, file paths or regex-like patterns within the node_modules folder to exclude from SWC transpilation.

  • modern.transpiler.excludePackages: [true|false] or [string[]] 如果为 true,则 Meteor 的软件包将继续使用 Babel。否则,输出应用内要从 SWC 转译中排除的软件包名称、文件路径或类似正则表达式的模式列表。

    ¥modern.transpiler.excludePackages: [true|false] or [string[]] If true, the Meteor’s packages will continue using Babel. Otherwise, a list of package names, file paths or regex-like patterns within the package to exclude from SWC transpilation.

  • modern.transpiler.excludeLegacy: [true|false] 如果为 true,则 Meteor 针对旧版浏览器的软件包将继续使用 Babel。

    ¥modern.transpiler.excludeLegacy: [true|false] If true, the Meteor’s bundle for legacy browsers will continue using Babel.

  • modern.transpiler.verbose: [true|false] 如果设置为 true,运行应用时会显示文件的转译过程。这有助于了解每个文件使用哪个转译器、应用了哪些回退机制,并允许你排除某些文件以始终使用 Babel 或完全迁移到 SWC。

    ¥modern.transpiler.verbose: [true|false] If true, the transpilation process for files is shown when running the app. This helps understand which transpiler is used for each file, what fallbacks are applied, and gives a chance to either exclude files to always use Babel or migrate fully to SWC.

迁移主题

¥Migration Topics

嵌套导入

¥Nested Imports

嵌套导入是 Meteor 打包器中特有的功能,与标准打包器不同。Meteor 在打包标准仍在发展阶段时引入了 Babel,并尝试了其自身的方案。此功能源自 reify 模块,可与 Babel 转译配合使用。SWC 不支持它们,因为它们从未标准化。

¥Nested imports are a Meteor-specific feature in its bundler, unlike standard bundlers. Meteor introduced them during a time when bundling standards were still evolving and experimented with its own approach. This feature comes from the reify module and works with Babel transpilation. SWC doesn't support them since they were never standardized.

嵌套导入示例:

¥Example with a nested import:

javascript
if (condition) {
  import { a as b } from "./c";
  console.log(b);
}

不使用嵌套导入(移至顶部):

¥Without a nested import (moved to top):

javascript
import { a as b } from "./c";

if (condition) {
  console.log(b);
}

背景信息,请参阅:为什么嵌套导入

¥For background, see: Why nested import.

"modern.transpiler": true 中,如果 SWC 找到 Babel,它会静默回退到 Babel(仅在 "verbose": true 中显示)。嵌套导入并非标准配置,大多数现代项目使用其他延迟加载方法。你可能希望将导入移至顶部或改用 require,让 SWC 处理文件并加快构建速度。不过,这个决定权在开发者手中,一些 Meteor 开发者出于正当理由使用它们。

¥With "modern.transpiler": true, if SWC finds one, it silently falls back to Babel (only shows in "verbose": true). Nested imports isn’t standard, most modern projects use other deferred loading methods. You might want to move imports to the top or use require instead, letting SWC handle the file and speeding up builds. Still, this decision is up to the devs, some Meteor devs use them for valid reasons.

导入别名

¥Import Aliases

Meteor Babel 允许你使用 babel-plugin-module-resolver 为导入路径定义别名。

¥Meteor Babel lets you define aliases for import paths with babel-plugin-module-resolver.

要在 SWC 中使用相同的别名,请将其添加到你的 .swcrc 中:

¥To use the same aliases in SWC, add them to your .swcrc:

json
{
  "jsc": {
    "baseUrl": "./",
    "paths": {
      "@ui/*": ["ui/*"]
    }
  }
}

这使你能够在导入中使用 @ui/components 而不是 ./ui/components

¥This enables you to use @ui/components instead of ./ui/components in your imports.

你可以使用 swc.config.js 根据环境变量定义不同的别名。

¥You can use swc.config.js to define different aliases based on an environment variable.

js
var mode = process.env.MODE_ENV;

var userAliases = {
  "@ui/*": ["user/*"],
};

var adminAliases = {
  "@ui/*": ["admin/*"],
};

module.exports = {
    jsc: {
        baseUrl: "./",
        paths: mode === "USER" ? userAliases : adminAliases,
    },
};

警告

SWC 仅解析导入的别名,而不解析 require 调用。

¥SWC only resolves aliases to imports, not require calls.

  • 导入

    ¥Imports

绑定导入会注入要使用的模块。

¥Binding imports inject a module to use.

javascript
// Binding imports
import Button from "@ui/button";
import { Button } from "@ui/button";

副作用导入会运行模块的代码。

¥Side-effect imports run the module’s code.

javascript
// Side effect import
import "@ui/button";
  • 需要调用

    ¥Require calls

可以导入值或运行模块代码。

¥Can import values or run the module’s code.

javascript
const { Button } = require("@ui/button");

require("@ui/button");

SWC 可以正确解析导入的别名,但无法解析 require 调用。对于 require 调用,请使用导入或相对路径。

¥SWC resolve aliases for imports correctly, but require calls won’t. For require calls, use an import or a relative path.

SWC 目前没有 类似 Babel 的模块解析器插件,这可能会影响未来的 require 调用。

¥SWC has no module-resolver plugin like Babel’s yet, which could affect require calls in the future.

JS 文件中的 JSX 语法

¥JSX Syntax in JS files

将应用迁移到使用 SWC 时,如果你在 .js 文件中包含 JSX,Meteor SWC 会回退到 Babel,因为 JSX 仅在 .jsx 文件中被识别。

¥When migrating your app to use SWC, Meteor SWC falls back to Babel if you include JSX in .js files, since JSX is only recognized in .jsx files.

要在 .js 文件中启用 JSX,请创建一个包含以下配置的 .swcrc 文件:

¥To enable JSX in .js files, create a .swcrc file with this config:

json
{
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "jsx": true
    }
  }
}

对于 TypeScript,请设置 "syntax":"typescript" 和 "tsx":改为 true。

¥For TypeScript, set "syntax": "typescript" and "tsx": true instead.

此方法会覆盖 Meteor 的内部 SWC 配置,以便 SWC 处理包含 React 组件的 .js.ts 文件,而不是回退到 Babel。

¥This overrides Meteor’s internal SWC config so SWC handles .js and .ts files with React components instead of falling back to Babel.

React 运行时

¥React Runtime

Meteor Babel 允许你使用 @babel/plugin-transform-react-jsx 运行时配置跳过在文件中导入 React 的步骤。

¥Meteor Babel lets you skip importing React in your files by using the @babel/plugin-transform-react-jsx runtime config.

要在 SWC 中使用相同的配置,请将其添加到你的 .swcrc 中:

¥To use the same config in SWC, add it to your .swcrc:

json
{
  "jsc": {
    "transform": {
      "react": {
        "runtime": "automatic"
      }
    }
  }
}

转换导入

¥Transform Imports

你可能已经使用 Meteor Babel 和 babel-plugin-transform-imports 插件重写了应用中的导入语句。

¥You might have used Meteor Babel with the babel-plugin-transform-imports plugin to rewrite imports in your app.

SWC 提供了一个类似的插件:@swc/plugin-transform-imports

¥SWC offers a similar plugin: @swc/plugin-transform-imports.

要切换到 SWC,请安装插件:

¥To switch to SWC, install the plugin:

bash
meteor npm install -D @swc/plugin-transform-imports

并将其添加到你的 .swcrc 包中:

¥and add it to your .swcrc:

json
{
  "jsc": {
    "experimental": {
      "plugins": [
        [
          "@swc/plugin-transform-imports",
          {
            "lodash": {
              "transform": "lodash/{{member}}",
              "preventFullImport": true
            }
          }
        ]
      ]
    }
  }
}

这告诉 SWC 替换,例如:

¥This tells SWC to replace, for example,

javascript
import { map } from "lodash"

with

javascript
import map from "lodash/map"

避免导入整个包并减小包的大小。

¥avoiding full-package imports and reducing bundle size.

你可以使用高级导入转换。请参阅测试套件以获取示例。

¥You can use advanced import transformations. See the test suite for examples.

私有属性

¥Private Properties

SWC 支持许多最新的 JS 语法特性,包括私有类属性,而 Meteor Babel 不支持这些特性。

¥SWC supports many of the most modern JS systax features, including private class properties, which Meteor Babel doesn’t.

只需启用 SWC,Meteor 就能正确解析类似这样的代码:

¥Just by enabling SWC, Meteor will parse properly code like:

javascript
class ClassWithPrivate {
  #privateField;
  #privateFieldWithInitializer = 42;
  
  #privateMethod() {}
  
  static #privateStaticField;
  static #privateStaticFieldWithInitializer = 42;

  static #privateStaticMethod() {}
}

你可以使用 .swcrc 文件选择不使用 SWC 选项中的私有属性(使用 "privateMethod" 设置)

¥You can opt-out of private properties in SWC options with "privateMethod" setting with the .swcrc file.

故障排除

¥Troubleshotting

如果你遇到问题,请尝试 meteor reset 或删除项目根目录中的 .meteor/local 文件夹。

¥If you run into issues, try meteor reset or delete the .meteor/local folder in the project root.

如需帮助或报告问题,请在 GitHubMeteor 论坛 上发帖。我们专注于提高 Meteor 的速度,你的反馈将对我们有所帮助。

¥For help or to report issues, post on GitHub or the Meteor forums. We’re focused on making Meteor faster and your feedback helps.

你可以通过运行 meteor profile 来比较启用 modern 前后的性能。分享你的结果,向他人展示进度。

¥You can compare performance before and after enabling modern by running meteor profile. Share your results to show progress to others.

查看现代打包器选项 可提升性能并访问更新的构建功能。

¥Check out modern bundler options to improve performance and access newer build features.