Skip to content

Commit

Permalink
refactor(module-tools): build (#4651)
Browse files Browse the repository at this point in the history
* test: improve module unit and integration test

* chore: delete libuild and libuild plugins

* chore: delete unuse dependencies and packages

* chore: deprecate dts.tsconfigPath and sourceType

* chore: adjust some logic about asset, css module and swc

* chore: set transformLodash false by default

* refactor: use hooks to achieve all module plugins

* feat: support debug mode

* feat: support banner, footer, hooks, resolve and tsconfig

* docs: adjust doc after refactor
  • Loading branch information
10Derozan authored Sep 22, 2023
1 parent 9bcba61 commit 602d1fb
Show file tree
Hide file tree
Showing 924 changed files with 6,068 additions and 65,570 deletions.
10 changes: 10 additions & 0 deletions .changeset/quick-plums-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@modern-js/plugin-module-node-polyfill': minor
'@modern-js/plugin-module-polyfill': minor
'@modern-js/plugin-module-banner': minor
'@modern-js/plugin-module-import': minor
'@modern-js/plugin-module-babel': minor
---

refactor(plugin-module): use buildConfig.hooks to realize afresh
refactor(plugin-module): 使用 buildConfig.hooks 重新实现各插件功能
37 changes: 37 additions & 0 deletions .changeset/soft-experts-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
'@modern-js/module-tools': minor
---

refactor(module-tools):

1. merge libuild to module tools, add buildConfig.hooks to support load, transform and renderChunk
2. support buildConfig.tsconfig, refine the scenarios for custom tsconfig, so replace dts.tsconfigPath with this.
3. disable buildConfig.transformLodash by default:
This optimisation was introduced in version 2.22.0 to reduce code size by modularising lodash import, but it may also cause some compatibility issues, so in version 2.32.0 a new transformLodash configuration has been added to manually disable this optimisation. In this version, this optimisation is turned off by default, and lodash is not processed separately by default.

4. only use swc transform when enable transformImport, transformLodash or externalHelpers.
swc conversion was introduced in version 2.16.0, but the implementation still has some problems, such as format cjs does not have "Annotate the CommonJS export names for ESM import in node", sourceType commonjs support is poor, etc. In this version, swc conversion is no longer used in full, and all kinds of limitations and judgements are removed, and only swc is used as a supplement to some features.

5. remove unuse dependecies and improve code quality.
6. support debug mode to print debug logs.
7. fix some css module bugs.
8. support buildConfig.jsx: preserve .
9. support glob input in js and dts generator.
10. support banner and footer.

refactor(module-tools):

1. 将 libuild 合入模块工程,添加 buildConfig.hooks,支持 load, transform 和 renderChunk 钩子。
2. 支持 buildConfig.tsconfig 配置,用来完善自定义 tsconfig 的场景,请用它来替换 dts.tsconfigPath
3. 默认禁用 buildConfig.transformLodash:
此优化是由 2.22.0 版本引入,通过模块化 lodash 的导入从而减小代码体积,但这也可能导致一些兼容性问题,因此在 2.32.0 版本新增了 transformLodash 配置,可以手动关闭此优化。在此版本,默认关闭此优化,默认不对 lodash 作单独的处理。

4. 只有在开启 transformImport, transformLodash 或 externalHelpers 时才使用 swc 转换。
swc 转换是在 2.16.0 版本引入,但实现仍存在一些问题,例如 format cjs 没有 “Annotate the CommonJS export names for ESM import in node”,sourceType commonjs 支持不佳等等,在此版本,不再全量使用 swc 转换,移除各种限制和判断,只使用 swc 作为部分功能的补充。

5. 移除未使用的依赖并提升代码质量。
6. 支持 debug 模式打印调试日志。
7. 修复一些 css module 问题。
8. 支持 buildConfig.jsx: preserve 选项。
9. 支持 glob 模式输入在 js 和 dts 生成器中。
10. 支持 banner 和 footer 配置。
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ lib/
compiled
.rpt2_cache/
packages/runtime/plugin-garfish/tests/**
tests/integration/libuild/
tests/integration/swc/fixtures/transform-fail/src/App.jsx
loader.cjs
7 changes: 2 additions & 5 deletions packages/cli/plugin-tailwind/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,9 @@ export const tailwindcssPlugin = (
config.style.postcss.plugins = [tailwindPlugin];
}

return config;
},

modifyLibuild(config, next) {
config.transformCache = false;
return next(config);

return config;
},
};
},
Expand Down
192 changes: 161 additions & 31 deletions packages/document/module-doc/docs/en/api/config/build-config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,47 @@ Whether to require peerDep dependencies for external projects
- **Type**: `boolean`
- **Default**: `true`


## banner

Provides the ability to inject content into the top and bottom of each JS , CSS and DTS file.

```ts
interface BannerAndFooter {
js?: string;
css?: string;
dts?: string;
}
```

- **Type**: `BannerAndFooter`
- **Default**: `{}`
- **Version**: `v2.36.0`

Let's say you want to add copyright information to JS and CSS files.

```ts
import { moduleTools, defineConfig } from '@edenx/module-tools';

const copyRight = `/*
© Copyright 2020 xxx.com or one of its affiliates.
* Some Sample Copyright Text Line
* Some Sample Copyright Text Line
*/`;

export default defineConfig({
plugins: [
moduleTools(),
],
buildConfig: {
banner: {
js: copyRight,
css: copyRight,
}
}
});
```

## buildType

The build type, `bundle` will package your code, `bundleless` will only do the code conversion
Expand Down Expand Up @@ -284,6 +325,41 @@ export default {
};
```

If the project is a TypeScript project, then you may need to add the following to the `.d.ts` file in the project source directory.

> If the `.d.ts` file does not exist, then you can create it manually.
```ts title="env.d.ts"
declare const YOUR_ADD_GLOBAL_VAR;
```

You can also replace environment variable:

```js
import { defineConfig } from '@modern-js/module-tools';
export default defineConfig({
buildConfig: {
define: {
'process.env.VERSION': JSON.stringify(process.env.VERSION || '0.0.0'),
},
},
});
```

With the above configuration, we can put the following code.

```js
// pre-compiler code
console.log(process.env.VERSION);
```

When executing `VERSION=1.0.0 modern build`, the conversion is:

```js
// compiled code
console.log('1.0.0');
```

:::tip
To prevent excessive global replacement substitution, it is recommended that the following two principles be followed when using

Expand All @@ -292,15 +368,6 @@ To prevent excessive global replacement substitution, it is recommended that the

:::

{/* ## disableSwcTransform
Starting with version 2.16.0, SWC Transform is enabled by default for code transformation. If you want to disable this feature, you can use this configuration. Only esbuild Transform is used in this case.
The use of SWC Transform can reduce the impact of auxiliary functions on the volume of the constructed product.
* **Type**: `boolean`
* **Default**: `false` */}

## dts

The dts file generates the relevant configuration, by default it generates.
Expand All @@ -313,7 +380,6 @@ The dts file generates the relevant configuration, by default it generates.
abortOnError: true,
distPath: './',
only: false,
tsconfigPath: './tsconfig.json',
}
```

Expand Down Expand Up @@ -376,38 +442,37 @@ export default defineConfig({
});
```

## dts.respectExternal

When set to `false`, the type of third-party packages will be excluded from the bundle, when set to `true`, it will determine whether third-party types need to be bundled based on [externals](#externals).
## dts.tsconfigPath

When bundle d.ts, export is not analyzed, so any third-party package type you use may break your build, which is obviously uncontrollable.
So we can avoid it with this configuration.
**deprecated**,use [tsconfig](#tsconfig) instead.

- **Type**: `boolean`
- **Default**: `true`
Specifies the path to the tsconfig file used to generate the type file.

```js title="modern.config.ts"
```ts title="modern.config.ts"
export default defineConfig({
buildConfig: {
dts: {
respectExternal: false,
tsconfigPath: './other-tsconfig.json',
},
},
});
```

## dts.tsconfigPath
## dts.respectExternal

Path to the tsconfig file
When set to `false`, the type of third-party packages will be excluded from the bundle, when set to `true`, it will determine whether third-party types need to be bundled based on [externals](#externals).

- **Type**: `string`
- **Default**: `. /tsconfig.json`
When bundle d.ts, export is not analyzed, so any third-party package type you use may break your build, which is obviously uncontrollable.
So we can avoid it with this configuration.

- **Type**: `boolean`
- **Default**: `true`

```js title="modern.config.ts"
export default defineConfig({
buildConfig: {
dts: {
tsconfigPath: './other-tsconfig.json',
respectExternal: false,
},
},
});
Expand Down Expand Up @@ -452,7 +517,7 @@ We have done many extensions based on the original esbuild build. Therefore, whe

By default, the output JS code may depend on helper functions to support the target environment or output format, and these helper functions will be inlined in the file that requires it.

When using SWC Transform for code transformation, you can enable the `externalHelpers` configuration to convert inline helper functions to import them from the external module `@swc/helpers`.
With this configuration, the code will be converted using SWC, it will inline helper functions to import them from the external module `@swc/helpers`.

- **Type**: `boolean`
- **Default**: `false`
Expand Down Expand Up @@ -515,6 +580,10 @@ export default defineConfig({
});
```

## footer

Same as the [banner](#banner) configuration for adding a comment at the end of the output file.

## format

Used to set the output format of JavaScript files. The options `iife` and `umd` only take effect when `buildType` is `bundle`.
Expand Down Expand Up @@ -564,7 +633,7 @@ export default defineConfig({
});
```

### format: 'umd'
### format: umd

`umd` stands for "Universal Module Definition" and is used to run modules in different environments such as browsers and Node.js. Modules in UMD format can be used in various environments, either as global variables or loaded as modules using module loaders like RequireJS.

Expand Down Expand Up @@ -666,6 +735,7 @@ export default defineConfig({
```

:::tip
If you don't need to convert JSX, you can set `jsx` to `preserve`, but don't [use swc](/guide/advance/in-depth-about-build#use-swc) to do the code conversion.
For more information about JSX Transform, you can refer to the following links:

- [React Blog - Introducing the New JSX Transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html).
Expand Down Expand Up @@ -763,6 +833,59 @@ export default {
};
```

## resolve

Custom module resolution options

### resolve.mainFields

A list of fields in package.json to try when parsing the package entry point.

- **Type**: `string[]`
- **Default**: depends on [platform](#platform)
- node: ['module', 'main']
- browser: ['module', 'browser', 'main']
- **Version**: `v2.36.0`

For example, we want to load the `js:source` field first:

```js title="modern.config.ts"
export default defineConfig({
buildConfig: {
resolve: {
mainFields: ['js:source', 'module', 'main'],
}
},
});
```

:::warning
`resolve.mainFields` has a lower priority than the exports field in package.json, and if an entry point is successfully resolved from exports, `resolve.mainFields` will be ignored.
:::

### resolve.jsExtentions

Support for implicit file extensions

- **Type**: `string[]`
- **Default**: `['.jsx', '.tsx', '.js', '.ts', '.json']`
- **Version**: `v2.36.0`


Do not use implicit file extensions for css files, currently Module only supports ['.less', '.css', '.sass', '.scss'] suffixes.

Node's parsing algorithm does not consider `.mjs` and `cjs` as implicit file extensions, so they are not included here by default, but can be included by changing this configuration:

```js title="modern.config.ts"
export default defineConfig({
buildConfig: {
resolve: {
jsExtentions: ['.mts', 'ts']
}
},
});
```

## sideEffects

Module sideEffects
Expand Down Expand Up @@ -1186,6 +1309,7 @@ export default defineConfig({
## transformImport

Using [SWC](https://swc.rs/) provides the same ability and configuration as [`babel-plugin-import`](https://github.com/umijs/babel-plugin-import).
With this configuration, the code will be converted using SWC.

- **Type**: `object[]`
- **Default**: `[]`
Expand Down Expand Up @@ -1216,10 +1340,12 @@ Specifies whether to modularize the import of [lodash](https://www.npmjs.com/pac

This optimization is implemented using [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash) and [swc-plugin-lodash](https://github.com/web-infra-dev/swc-plugins/tree/main/crates/plugin_lodash) under the hood.

With this configuration, the code will be converted using SWC.

- **Type**: `boolean`
- **Default**: `true`
- **Default**: `false`

This option is enabled by default, and Modern.js Module will automatically redirects the code references of `lodash` to sub-paths.
When you enable this, Modern.js Module will automatically redirects the code references of `lodash` to sub-paths.

For example:

Expand All @@ -1241,14 +1367,18 @@ const addOne = _add(1);
_map([1, 2, 3], addOne);
```

### Disabling the Transformation
## tsconfig

In some cases, the import transformation of `lodash` may generate unexpected code. In such cases, you can manually disable this optimization:
Path to the tsconfig file

- **Type**: `string`
- **Default**: `tsconfig.json`
- **Version**: `v2.36.0`

```js title="modern.config.ts"
export default defineConfig({
buildConfig: {
transformLodash: false,
tsconfig: 'tsconfig.build.json',
},
});
```
Expand Down
Loading

0 comments on commit 602d1fb

Please sign in to comment.