Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swc support #167

Merged
merged 10 commits into from
Nov 24, 2022
Merged

swc support #167

merged 10 commits into from
Nov 24, 2022

Conversation

liaoyu
Copy link
Collaborator

@liaoyu liaoyu commented Jul 25, 2022

使用时建议先仅在开发环境或者在内部 admin 系统开启

支持 swc 提升打包速度

开启后 swc-loader 将替换 babel-loaderts-loader,开启方式如下:

"optimization": {
  "swc": true
}

开启 swc 注意点

  • swc 不支持 ts 的类型检查,导致 transpileOnlyWhenDev 开关无效,如果需要在打包中校验类型可在打包构建步骤中加入 tsc --noEmit 来做类型检查; TypeScript type checker swc-project/swc#571
  • swc 不支持使用项目中 typescript 进行编译,导致 useProjectTypeScript 开关无效
  • swc 不会读取项目中的 tsconfig.json 配置
  • 自定义 transform 的配置中如果包含 babelOptions,swc 将不会开启
  • JSX 中不支持 spread operator 写法,ts-loader 是支持的,但 babel 也不支持 JSX parsing panics when using the spread operator swc-project/swc#2037
  • browserslist 在 swc 中的行为相较 babel 有所差异,以配置的 extends @qiniu/build-config/portal 为例,使用 swc 后 bundle 中会包含 let const async await 箭头函数 语法 preset-env: Switch to browserslist-rs swc-project/swc#2781

spread operator 语法更改方式

image

可以改成

image

测试

portal-fusion 打包测试为例,开启后整体打包耗时下降 30% 左右

@nighca
Copy link
Collaborator

nighca commented Jul 25, 2022

开启后 swc-loader 将替换 babel-loader、ts-loader

应该会有一些代价吧?比如印象中 swc 对 babel plugin 支持得一般,我们现在在用的 babel plugin 受影响大吗?以及 ts 的使用是不是有影响

@liaoyu
Copy link
Collaborator Author

liaoyu commented Jul 25, 2022

应该会有一些代价吧?比如印象中 swc 对 babel plugin 支持得一般,我们现在在用的 babel plugin 受影响大吗?以及 ts 的使用是不是有影响

目前拿 portal-fusion 测试遇到的一个问题是 mobx 的 observable 如果没设置初始值不能正常 reactive,用 babel 的能正常响应该是先经过 ts-loader 再经 babel-loader 转一次才没这个问题,相关 issue swc-project/swc#3232

这个后面我还需要看看怎么处理好;更多的场景还没仔细测

@nighca
Copy link
Collaborator

nighca commented Jul 26, 2022

你说的是要靠测试发现的细微的行为差异;有那种明面上就存在的问题吗,比如某个我们在用的 babel plugin swc 不支持?或者某个我们在用的 ts-loader / ts-compiler 配置 swc 没有提供对应的能力?

@liaoyu
Copy link
Collaborator Author

liaoyu commented Jul 26, 2022

你说的是要靠测试发现的细微的行为差异;有那种明面上就存在的问题吗,比如某个我们在用的 babel plugin swc 不支持?或者某个我们在用的 ts-loader / ts-compiler 配置 swc 没有提供对应的能力?

了解,这些我一一确认下

Copy link
Collaborator

@nighca nighca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看了下实现,整体做法我没问题~

这个 PR 看上去最麻烦的还是确认行为差异 🤣

@liaoyu
Copy link
Collaborator Author

liaoyu commented Jul 27, 2022

这个 PR 看上去最麻烦的还是确认行为差异 🤣

是的,做之前我粗略看了下我们使用到的 babel-plugin 倒都是支持的 https://swc.rs/docs/migrating-from-babel

使用方在 build-config.json 里自定义配置的 transforms 逻辑处理起来感觉会比较麻烦

@nighca
Copy link
Collaborator

nighca commented Jul 27, 2022

使用方在 build-config.json 里自定义配置的 transforms 逻辑处理起来感觉会比较麻烦

是指 babelOptions 这样的自定义的 babel 配置吗?是的话这种倒是好处理,如果发现有自定义的 babel 配置,就退回到走 babel 就好;Next.js 也是这么处理的,它是检测项目中是否有 .bebelrc,如果有,就退回到走 babel 而不走 swc

现在会用自定义 babel 配置的项目应该很少(这个配置甚至没有写在对外文档里,算是个后门..),所以影响不大;退回 babel 的时候我们也可以打个 warning 啥的,推动项目跟我们一起处理下

@nighca
Copy link
Collaborator

nighca commented Jul 27, 2022

P.S. 现在再看,当初把 Transform.Babel 取名为 babel 其实不太好,可能就叫 Transform.Js / Transform.Es 之类会更好一点

@liaoyu
Copy link
Collaborator Author

liaoyu commented Jul 27, 2022

是指 babelOptions 这样的自定义的 babel 配置吗?

是的

如果发现有自定义的 babel 配置,就退回到走 babel 就好

哈哈哈,我没想到还能这么搞 😆

@liaoyu liaoyu changed the title [WIP] swc support swc support Sep 1, 2022
@liaoyu
Copy link
Collaborator Author

liaoyu commented Sep 1, 2022

测试发现用 babel 时这一行 not ie 11 删除与否对打包结果没有影响,不确定是不是因为 browserslist-stats.json 里一些对 js 特性支持不够的小众浏览器包含在 > 0.1%

image

另在 babel在线工具 中可以发现 ,targets 加上 ie 11 后才会将 let const 转换成 var

image

@doxiaodong
Copy link
Contributor

portal-fusion
多年后还是这个名字

Copy link
Collaborator

@nighca nighca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

另外,build-config.md 里是不是要加上 swc 相关的文档?PR 中的“开启 swc 注意点”也补充过去?

src/webpack/swc.ts Outdated Show resolved Hide resolved
decorators: true
},
transform: {
legacyDecorator: true,
Copy link
Collaborator

@nighca nighca Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对于 TS 项目,这里的一些配置是不是需要根据 tsconfig 的内容来决定?

另外我看 PR 说明里提到

  • swc 不会读取项目中的 tsconfig.json 配置

这个听着不太科学啊,尤其是像 baseUrl 这样的信息,如果不去读,这里能正确地把项目编出来吗?

Copy link
Collaborator Author

@liaoyu liaoyu Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

现在能正常编是因为 swc 自己维护了 baseUrl 配置
https://swc.rs/docs/configuration/compilation#jscbaseurl

swc 的部分配置(如 baseUrl / pathstsconfig 也有的字段)我从 tsconfig 文件来读取?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对的,除了 builder 希望写死的配置,其他都应该尽量从项目的 tsconfig 文件来会合理一点,因为我们的项目确实会用 tsconfig 文件来配置构建行为

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已补充~ 1679c2b

Copy link
Collaborator Author

@liaoyu liaoyu Nov 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

更正下,我上面对 swc 依赖 tsconfig.jsonbaseUrl 配置理解有误;跟 webpack 结合使用时,它的模块查找仍是使用 webpack 的 resolve.modules

baseUrl 生效场景是完全使用 swcpack 打包时的场景,用法上也挺坑的 swc-project/swc#2725 ,整体觉得 swc 还不太完善

Copy link
Collaborator

@nighca nighca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

另外 #167 (review) 这里提到的 build-config.md 还需要处理下

import { abs } from '../utils/paths'

/** read and parse tsconfig.json */
function readTsConfig() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIP: 严谨点说,这个函数返回的是 ts config 中的 compilerOptions 而不是 ts config?

const compilerOptions = readTsConfig()

if (compilerOptions != null) {
return merge(swcOptions, convertTsConfig(compilerOptions))
Copy link
Collaborator

@nighca nighca Nov 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lodash merge 的行为应该不是这里想要的?比如

merge(
  { paths: ['a', 'b'] },
  { paths: ['c'] }
)

的结果是

{ paths: ['c', 'b'] }

我理解

{ paths: ['c'] }

才是预期的?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, a4a0815

function customizer(srcValue, targetValue) {
  if (_.isArray(targetValue)) {
    return targetValue
  }
}

_.mergeWith(
  {
    arr: [1, 2, 4],
    paths: ['a', 'b'],
    obj: { name: 'obj1', origin: 222 }
  },
  {
    paths: ['c'],
    obj: { name: 'obj2', value: 123 }
  },
  customizer
)

image

Copy link
Collaborator

@nighca nighca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕍

@liaoyu liaoyu merged commit 12a612e into qiniu:master Nov 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants