Skip to content

Commit

Permalink
feat: plugin-swc
Browse files Browse the repository at this point in the history
  • Loading branch information
wanchun committed Mar 1, 2023
1 parent 8afec60 commit 99749c1
Show file tree
Hide file tree
Showing 23 changed files with 418 additions and 141 deletions.
1 change: 1 addition & 0 deletions README.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ It mainly has the following functions:
| [@fesjs/plugin-monaco-editor](http://fesjs.mumblefe.cn/reference/plugin/plugins/editor.html#%E4%BB%8B%E7%BB%8D) | Provide code editor capability, based on `monaco-editor` (code editor used by VS Code) |
| [@fesjs/plugin-pinia](http://fesjs.mumblefe.cn/reference/plugin/plugins/pinia.html) | state manager |
| [@fesjs/plugin-watermark](http://fesjs.mumblefe.cn/reference/plugin/plugins/watermark.html) | watermark |
| [@fesjs/plugin-swc](http://fesjs.mumblefe.cn/reference/plugin/plugins/swc.html) | use swc-loader |

## As easy as counting 1, 2, 3
use `yarn`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Fes.js 是一个好用的前端应用解决方案。提供覆盖编译构建到
| [@fesjs/plugin-windicss](http://fesjs.mumblefe.cn/reference/plugin/plugins/windicss.html) | 基于 `windicss`,提供原子化 CSS 能力 |
| [@fesjs/plugin-pinia](http://fesjs.mumblefe.cn/reference/plugin/plugins/pinia.html) | pinia,状态处理 |
| [@fesjs/plugin-watermark](http://fesjs.mumblefe.cn/reference/plugin/plugins/watermark.html) | 水印 |

| [@fesjs/plugin-swc](http://fesjs.mumblefe.cn/reference/plugin/plugins/swc.html) | 使用swc-loader构建 |

## 像数 1, 2, 3 一样容易
使用 `yarn`
Expand Down
1 change: 1 addition & 0 deletions build.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
'fes-plugin-pinia',
'fes-plugin-windicss',
'fes-plugin-watermark',
'fes-plugin-swc',
],
copy: [],
};
1 change: 1 addition & 0 deletions docs/.vuepress/configs/sidebar/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const zh: SidebarConfig = {
'/reference/plugin/plugins/editor.md',
'/reference/plugin/plugins/pinia.md',
'/reference/plugin/plugins/watermark.md',
'/reference/plugin/plugins/swc.md',
],
},
{
Expand Down
1 change: 0 additions & 1 deletion docs/guide/builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

- 选用 Vite 构建,安装 `npm i @fesjs/builder-vite` 依赖即可。
- 选用 Webpack 构建,安装 `npm i @fesjs/builder-webpack` 依赖即可。
- Webpack构建支持用babel+terser和swc两种编译方式,如选用swc,安装`npm i @swc/core` 同时配置额外传`swcLoader:{}`,具体可以查看[配置](../reference/config)

## 使用差异

Expand Down
7 changes: 0 additions & 7 deletions docs/reference/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,13 +459,6 @@ export default {

配置额外的 `babel` 插件集。

### swcLoader
- 类型: `object`
- 默认值: `undefined`
- 详情:

传对象时使用swc进行编译和压缩,[swc配置](https://swc.rs/docs/configuration/swcrc)
默认usage模式
### extraPostCSSPlugins

- 类型: `array`
Expand Down
3 changes: 2 additions & 1 deletion docs/reference/plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
| [@fesjs/plugin-enums](./plugins/enums.md) | 提供统一的枚举存取及丰富的函数来处理枚举 |
| [@fesjs/plugin-icon](./plugins/icon.md) | svg 文件自动注册为组件 |
| [@fesjs/plugin-jest](./plugins/jest.md) | 基于 `Jest`,提供单元测试、覆盖测试能力 |
| [ @fesjs/plugin-layout](./plugins/layout.md) | 简单的配置即可拥有布局,包括导航以及侧边栏 |
| [@fesjs/plugin-layout](./plugins/layout.md) | 简单的配置即可拥有布局,包括导航以及侧边栏 |
| [@fesjs/plugin-locale](./plugins/locale.md) | 基于 `Vue I18n`,提供国际化能力 |
| [@fesjs/plugin-model](./plugins/model.md) | 简易的数据管理方案 |
| [@fesjs/plugin-request](./plugins/request.md) | 基于 `Axios` 封装的 request,内置防止重复请求、请求节流、错误处理等功能 |
Expand All @@ -18,6 +18,7 @@
| [@fesjs/plugin-windicss](./plugins/windicss.md) | 基于 `windicss`,提供原子化 CSS 能力 |
| [@fesjs/plugin-pinia](./plugins/pinia.md) | 基于 `pinia`,提供状态管理 |
| [@fesjs/plugin-watermark](./plugins/watermark.md) | 水印 |
| [@fesjs/plugin-swc](./plugins/swc.md) | swc |

## 架构

Expand Down
30 changes: 30 additions & 0 deletions docs/reference/plugin/plugins/swc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# @fesjs/plugin-swc

## 介绍
webpack 启用 swc,构建速度更快!


## 启用方式
`package.json` 中引入依赖:
```json
{
"dependencies": {
"@fesjs/fes": "^3.0.0",
"@fesjs/plugin-swc": "^3.0.0"
},
}
```

## 编译时配置
传对象时使用swc进行编译和压缩,[loader配置](https://swc.rs/docs/configuration/swcrc),默认usage模式。
```js
export default {
swc: {
loader: {
env: {
coreJs: '3.27',
},
}
},
}
```
2 changes: 0 additions & 2 deletions packages/fes-builder-webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"@babel/preset-env": "^7.16.4",
"@babel/preset-typescript": "^7.15.0",
"@fesjs/utils": "3.0.0-rc.2",
"@swc/css": "^0.0.18",
"@vue/babel-plugin-jsx": "^1.1.1",
"autoprefixer": "^10.2.4",
"babel-loader": "^8.2.2",
Expand All @@ -56,7 +55,6 @@
"postcss-loader": "^4.2.0",
"postcss-safe-parser": "^6.0.0",
"style-loader": "^2.0.0",
"swc-loader": "^0.2.3",
"terser-webpack-plugin": "^5.3.6",
"vue-loader": "^16.1.2",
"webpack": "^5.69.0",
Expand Down
1 change: 0 additions & 1 deletion packages/fes-builder-webpack/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export default function () {
require.resolve('./plugins/features/postcssLoader'),
require.resolve('./plugins/features/nodeModulesTransform'),
require.resolve('./plugins/features/vueLoader'),
require.resolve('./plugins/features/swcLoader'),

// commands
require.resolve('./plugins/commands/build'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
// 根据 entry 将文件输出到不同的文件夹

import { deepmerge } from '@fesjs/utils';
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';

function createRules({ isDev, webpackConfig, config, lang, test, loader, options, browserslist, styleLoaderOption }) {
function applyLoaders(rule, cssLoaderOption = {}) {
Expand Down Expand Up @@ -98,7 +97,7 @@ export default function createCssWebpackConfig({ isDev, config, webpackConfig, b
chunkFilename: '[id].[contenthash:8].css',
},
]);
webpackConfig.optimization.minimizer('css').use(require.resolve('css-minimizer-webpack-plugin'), [{ minify: CssMinimizerPlugin.swcMinify }]);
webpackConfig.optimization.minimizer('css').use(require.resolve('css-minimizer-webpack-plugin'), [{}]);
}

return (options) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import createVueWebpackConfig from './vue';
import createDefineWebpackConfig from './define';
import createMinimizerWebpackConfig from './minimizer';
import createHtmlWebpackConfig from './html';
import { buildSwcOptions } from './swcOptions';

const DEFAULT_EXCLUDE_NODE_MODULES = [
'vue',
Expand Down Expand Up @@ -53,7 +52,6 @@ function handleAlias({ api, webpackConfig }) {
export default async function getConfig({ api, cwd, config, env, entry = {}, modifyBabelOpts, modifyBabelPresetOpts, chainWebpack, headScripts, publicPath }) {
const isDev = env === 'development';
const isProd = env === 'production';
const useSwc = !!config.swcLoader;
const webpackConfig = new Config();
const absoluteOutput = join(cwd, config.outputPath || 'dist');

Expand Down Expand Up @@ -114,6 +112,13 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod
.type('asset/source');

const { targets, browserslist } = api.utils.getTargetsAndBrowsersList({ config });
const babelOpts = await getBabelOpts({
cwd,
config,
modifyBabelOpts,
modifyBabelPresetOpts,
targets,
});

// --------------- js -----------
// https://webpack.docschina.org/configuration/module/#resolve-fully-specified
Expand All @@ -122,106 +127,43 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod
.test(/\.m?jsx?$/)
.resolve.set('fullySpecified', false);

if (useSwc) {
webpackConfig.module
.rule('js')
.test(/\.(js|mjs)$/)
webpackConfig.module
.rule('js')
.test(/\.(js|mjs|jsx|ts|tsx)$/)
.exclude.add((filepath) => {
// always transpile js in vue files
if (/(\.vue|\.jsx)$/.test(filepath)) {
return false;
}
// Don't transpile node_modules
.exclude.add(/node_modules/)
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, false, false));
webpackConfig.module
.rule('jsx')
.test(/\.jsx$/)
.exclude.add(/node_modules/)
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, true, false));
return /node_modules/.test(filepath);
})
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.options(babelOpts);

// 为了避免第三方依赖包编译不充分导致线上问题,默认对 node_modules 也进行全编译,只在生产构建的时候进行
if (isProd) {
const transpileDepRegex = genTranspileDepRegex(config.nodeModulesTransform.exclude);
webpackConfig.module
.rule('ts')
.test(/\.ts$/)
.exclude.add(/node_modules/)
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, false, true));
webpackConfig.module
.rule('tsx')
.test(/\.tsx$/)
.exclude.add(/node_modules/)
.rule('js-in-node_modules')
.test(/\.(js|mjs)$/)
.include.add(/node_modules/)
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, true, true));
// 为了避免第三方依赖包编译不充分导致线上问题,默认对 node_modules 也进行全编译,只在生产构建的时候进行
if (isProd) {
// const cjsReg = [/css-loader/, /vue-loader/].concat(config.swcLoader?.cjsPkg || []);
const transpileDepRegex = genTranspileDepRegex(config.nodeModulesTransform.exclude);
webpackConfig.module
.rule('node_modules')
.test(/\.(js|mjs)$/)
.include.add(/node_modules/)
.end()
.exclude.add((filepath) => {
if (transpileDepRegex && transpileDepRegex.test(filepath)) {
return true;
}
return false;
})
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, false, false));
}
} else {
const babelOpts = await getBabelOpts({
cwd,
config,
modifyBabelOpts,
modifyBabelPresetOpts,
targets,
});
webpackConfig.module
.rule('js')
.test(/\.(js|mjs|jsx|ts|tsx)$/)
.exclude.add((filepath) => {
// always transpile js in vue files
if (/(\.tsx|\.ts|\.jsx)$/.test(filepath)) {
return false;
if (transpileDepRegex && transpileDepRegex.test(filepath)) {
return true;
}
// Don't transpile node_modules
return /node_modules/.test(filepath);

return false;
})
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.options(babelOpts);

// 为了避免第三方依赖包编译不充分导致线上问题,默认对 node_modules 也进行全编译,只在生产构建的时候进行
if (isProd) {
const transpileDepRegex = genTranspileDepRegex(config.nodeModulesTransform.exclude);
webpackConfig.module
.rule('js-in-node_modules')
.test(/\.(js|mjs)$/)
.include.add(/node_modules/)
.end()
.exclude.add((filepath) => {
if (transpileDepRegex && transpileDepRegex.test(filepath)) {
return true;
}

return false;
})
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.options(babelOpts);
}
}

// --------------- css -----------
const createCSSRule = createCssWebpackConfig({
isDev,
Expand Down Expand Up @@ -319,13 +261,15 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod
isProd,
config,
webpackConfig,
swcOptions: useSwc ? buildSwcOptions(targets, config, false, false, true) : undefined,
});

// --------------- chainwebpack -----------
if (chainWebpack) {
await chainWebpack(webpackConfig, {
createCSSRule,
env,
targets,
browserslist,
webpack,
});
}
Expand All @@ -334,6 +278,8 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod
await config.chainWebpack(webpackConfig, {
createCSSRule,
env,
targets,
browserslist,
webpack,
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { deepmerge } from '@fesjs/utils';
import TerserPlugin from 'terser-webpack-plugin';

const defaultTerserOptions = {
compress: {
Expand Down Expand Up @@ -38,22 +37,14 @@ const defaultTerserOptions = {
},
};

const terserOptions = (config, swcOptions) => {
if (swcOptions) {
return {
terserOptions: swcOptions.jsc?.minify,
minify: TerserPlugin.swcMinify,
};
}
return {
terserOptions: deepmerge(defaultTerserOptions, config.terserOptions || {}),
extractComments: false,
};
};
const terserOptions = (config) => ({
terserOptions: deepmerge(defaultTerserOptions, config.terserOptions || {}),
extractComments: false,
});

export default function createMinimizerWebpackConfig({ isProd, config, webpackConfig, swcOptions }) {
export default function createMinimizerWebpackConfig({ isProd, config, webpackConfig }) {
if (isProd) {
webpackConfig.optimization.minimizer('terser').use(require.resolve('terser-webpack-plugin'), [terserOptions(config, swcOptions)]);
webpackConfig.optimization.minimizer('terser').use(require.resolve('terser-webpack-plugin'), [terserOptions(config)]);
}
if (process.env.FES_ENV === 'test') {
webpackConfig.optimization.minimize(false);
Expand Down
10 changes: 0 additions & 10 deletions packages/fes-builder-webpack/src/plugins/features/swcLoader.js

This file was deleted.

Loading

0 comments on commit 99749c1

Please sign in to comment.