From 602d1fb91e61080c167738aa2d7d6550b2fbe684 Mon Sep 17 00:00:00 2001 From: 10Derozan Date: Fri, 22 Sep 2023 11:46:57 +0800 Subject: [PATCH] refactor(module-tools): build (#4651) * 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 --- .changeset/quick-plums-heal.md | 10 + .changeset/soft-experts-roll.md | 37 + .eslintignore | 1 - packages/cli/plugin-tailwind/src/cli.ts | 7 +- .../docs/en/api/config/build-config.mdx | 192 +- .../en/guide/advance/in-depth-about-build.md | 169 +- .../docs/zh/api/config/build-config.mdx | 182 +- .../zh/guide/advance/in-depth-about-build.md | 164 +- .../plugins/official-list/plugin-banner.mdx | 5 + .../generators/base-generator/package.json | 1 + .../generators/bff-generator/package.json | 1 + .../changeset-generator/package.json | 1 + .../dependence-generator/package.json | 1 + .../generator-generator/package.json | 1 + .../generators/module-generator/package.json | 1 + .../module-test-generator/package.json | 1 + .../monorepo-generator/package.json | 1 + .../generators/mwa-generator/package.json | 1 + .../packages-generator/package.json | 1 + .../router-v5-generator/package.json | 1 + .../generators/rspack-generator/package.json | 1 + .../generators/server-generator/package.json | 1 + .../generators/ssg-generator/package.json | 1 + .../storybook-generator/package.json | 1 + .../tailwindcss-generator/package.json | 1 + .../generators/test-generator/package.json | 1 + .../generators/upgrade-generator/package.json | 1 + .../plugins/generator-plugin/package.json | 1 + packages/libuild/libuild-core/.eslintrc.cjs | 14 - packages/libuild/libuild-core/.gitignore | 4 - packages/libuild/libuild-core/.mocharc.js | 7 - packages/libuild/libuild-core/CHANGELOG.md | 47 - packages/libuild/libuild-core/LICENSE.md | 21 - packages/libuild/libuild-core/README.md | 5 - .../libuild/libuild-core/api-extractor.json | 48 - packages/libuild/libuild-core/package.json | 97 - .../libuild/libuild-core/scripts/build.ts | 238 - .../libuild-core/src/bundler/adapter.ts | 405 - .../libuild/libuild-core/src/bundler/index.ts | 320 - .../libuild-core/src/bundler/resolve.ts | 153 - .../libuild-core/src/constants/config.ts | 4 - .../libuild-core/src/constants/error.ts | 8 - .../libuild-core/src/constants/plugins.ts | 3 - .../libuild-core/src/constants/regExp.ts | 1 - .../libuild/libuild-core/src/core/index.ts | 262 - .../libuild/libuild-core/src/core/resolve.ts | 115 - .../libuild-core/src/core/transform.ts | 32 - .../libuild/libuild-core/src/error/error.ts | 227 - .../libuild/libuild-core/src/error/failure.ts | 59 - .../libuild/libuild-core/src/error/index.ts | 3 - .../libuild/libuild-core/src/error/utils.ts | 140 - packages/libuild/libuild-core/src/index.ts | 3 - packages/libuild/libuild-core/src/logger.ts | 76 - .../libuild/libuild-core/src/plugins/asset.ts | 157 - .../libuild-core/src/plugins/format-cjs.ts | 28 - .../src/plugins/getInternalPlugin.ts | 37 - .../libuild/libuild-core/src/plugins/json.ts | 26 - .../libuild-core/src/plugins/metafile.ts | 21 - .../libuild-core/src/plugins/minify.ts | 68 - .../libuild-core/src/plugins/resolve.ts | 46 - .../libuild-core/src/plugins/style/index.ts | 62 - .../libuild/libuild-core/src/plugins/watch.ts | 107 - .../libuild-core/src/plugins/write-file.ts | 81 - .../libuild/libuild-core/src/types/builder.ts | 240 - .../libuild-core/src/types/callback.ts | 1 - .../libuild-core/src/types/config/asset.ts | 16 - .../libuild-core/src/types/config/index.ts | 219 - .../libuild-core/src/types/config/resolve.ts | 20 - .../libuild-core/src/types/config/style.ts | 71 - .../libuild/libuild-core/src/types/error.ts | 89 - .../libuild-core/src/types/global.d.ts | 1 - .../libuild/libuild-core/src/types/index.ts | 5 - .../libuild/libuild-core/src/types/logger.ts | 39 - .../libuild/libuild-core/src/utils/index.ts | 3 - .../libuild-core/src/utils/normalizeConfig.ts | 117 - .../src/utils/normalizeSourceMap.ts | 19 - .../test/dts/define-config.test-d.ts | 124 - .../libuild-core/test/dts/exist.test-d.ts | 36 - .../libuild-core/test/unit/findEntry.test.ts | 10 - .../libuild-core/test/unit/getAllDep.test.ts | 13 - .../test/unit/style/rebaseUrl.test.ts | 41 - .../libuild/libuild-core/tsconfig.build.json | 10 - packages/libuild/libuild-core/tsconfig.json | 11 - .../libuild-plugin-babel/.eslintrc.cjs | 3 - .../libuild/libuild-plugin-babel/CHANGELOG.md | 33 - .../libuild/libuild-plugin-babel/README.md | 28 - .../libuild-plugin-babel/modern.config.js | 15 - .../libuild/libuild-plugin-babel/package.json | 30 - .../libuild/libuild-plugin-babel/src/index.ts | 36 - .../libuild-plugin-babel/tsconfig.json | 11 - .../.eslintrc.cjs | 3 - .../libuild-plugin-node-polyfill/CHANGELOG.md | 43 - .../libuild-plugin-node-polyfill/README.md | 24 - .../modern.config.js | 28 - .../libuild-plugin-node-polyfill/package.json | 51 - .../libuild-plugin-node-polyfill/src/index.ts | 112 - .../tsconfig.json | 11 - .../libuild/libuild-plugin-svgr/.eslintrc.cjs | 3 - .../libuild/libuild-plugin-svgr/CHANGELOG.md | 33 - .../libuild/libuild-plugin-svgr/README.md | 30 - .../libuild-plugin-svgr/modern.config.js | 15 - .../libuild/libuild-plugin-svgr/package.json | 31 - .../libuild/libuild-plugin-svgr/src/index.ts | 43 - .../libuild/libuild-plugin-svgr/tsconfig.json | 10 - .../libuild/libuild-plugin-swc/.eslintrc.cjs | 7 - .../libuild/libuild-plugin-swc/CHANGELOG.md | 50 - .../libuild/libuild-plugin-swc/package.json | 31 - .../libuild-plugin-swc/scripts/build.ts | 7 - .../libuild-plugin-swc/src/constants.ts | 3 - .../libuild/libuild-plugin-swc/src/es5.ts | 33 - .../libuild/libuild-plugin-swc/src/index.ts | 7 - .../libuild/libuild-plugin-swc/src/legacy.ts | 66 - .../libuild-plugin-swc/src/transform.ts | 134 - .../libuild/libuild-plugin-swc/src/umd.ts | 51 - .../libuild/libuild-plugin-swc/src/utils.ts | 35 - .../libuild/libuild-plugin-swc/tsconfig.json | 11 - packages/libuild/libuild-utils/.eslintrc.cjs | 3 - packages/libuild/libuild-utils/.gitignore | 2 - packages/libuild/libuild-utils/.mocharc.js | 7 - packages/libuild/libuild-utils/CHANGELOG.md | 17 - packages/libuild/libuild-utils/package.json | 24 - packages/libuild/libuild-utils/src/assert.ts | 19 - .../libuild/libuild-utils/src/deepMerge.ts | 23 - packages/libuild/libuild-utils/src/index.ts | 3 - .../libuild-utils/src/resolvePathAndQuery.ts | 45 - .../libuild/libuild-utils/test/assert.test.ts | 71 - .../libuild-utils/test/deepMerge.test.ts | 48 - .../test/resolvePathAndQuery.test.ts | 36 - .../libuild/libuild-utils/tsconfig.build.json | 7 - packages/libuild/libuild-utils/tsconfig.json | 13 - .../module/plugin-module-babel/package.json | 37 +- .../module/plugin-module-babel/src/index.ts | 59 +- .../module/plugin-module-banner/package.json | 41 +- .../module/plugin-module-banner/src/index.ts | 8 +- .../module/plugin-module-import/package.json | 37 +- .../module/plugin-module-import/src/index.ts | 46 +- .../plugin-module-main-fields/.eslintrc.js | 8 - .../plugin-module-main-fields/.npmignore | 31 - .../plugin-module-main-fields/CHANGELOG.md | 357 - .../module/plugin-module-main-fields/LICENSE | 21 - .../plugin-module-main-fields/README.md | 5 - .../plugin-module-main-fields/jest.config.js | 7 - .../modern.config.js | 5 - .../plugin-module-main-fields/package.json | 47 - .../plugin-module-main-fields/src/index.ts | 26 - .../plugin-module-main-fields/tsconfig.json | 11 - .../plugin-module-node-polyfill/package.json | 64 +- .../src/globals.js | 0 .../plugin-module-node-polyfill/src/index.ts | 114 +- .../src/mock/child_process.js | 0 .../src/mock/cluster.js | 0 .../src/mock/dgram.js | 0 .../src/mock/dns.js | 0 .../src/mock/fs.js | 0 .../src/mock/module.js | 0 .../src/mock/net.js | 0 .../src/mock/readline.js | 0 .../src/mock/repl.js | 0 .../src/mock/tls.js | 0 .../plugin-module-node-polyfill/src/utils.ts | 44 + .../plugin-module-polyfill/package.json | 50 +- .../plugin-module-polyfill/src/index.ts | 54 +- .../module/plugin-module-target/.eslintrc.js | 8 - .../module/plugin-module-target/.npmignore | 31 - .../module/plugin-module-target/CHANGELOG.md | 357 - packages/module/plugin-module-target/LICENSE | 21 - .../module/plugin-module-target/README.md | 13 - .../plugin-module-target/jest.config.js | 7 - .../plugin-module-target/modern.config.js | 5 - .../module/plugin-module-target/package.json | 47 - .../module/plugin-module-target/src/index.ts | 17 - .../module/plugin-module-target/tsconfig.json | 11 - packages/solutions/module-tools/.eslintrc.js | 4 +- .../solutions/module-tools/jest.config.js | 11 - .../solutions/module-tools/modern.config.js | 8 - packages/solutions/module-tools/package.json | 113 +- packages/solutions/module-tools/src/build.ts | 15 +- .../module-tools/src/builder/build.ts | 312 +- .../module-tools/src/builder/clear.ts | 11 +- .../module-tools/src/builder/copy.ts | 16 +- .../module-tools/src/builder/dts/rollup.ts | 33 +- .../module-tools/src/builder/dts/tsc.ts | 41 +- .../src/builder/esbuild/adapter.ts | 329 + .../module-tools/src/builder/esbuild/hook.ts} | 12 +- .../module-tools/src/builder/esbuild/index.ts | 295 + .../src/builder/esbuild/resolve.ts | 101 + .../src/builder/esbuild}/sourcemap.ts | 5 +- .../src/builder/esbuild/transform.ts | 24 + .../module-tools/src/builder/esbuild/watch.ts | 93 + .../src/builder/esbuild/write-file.ts | 69 + .../module-tools/src/builder/feature/asset.ts | 160 + .../src/builder/feature/format-cjs.ts | 25 + .../module-tools/src/builder/feature/index.ts | 58 + .../module-tools/src/builder/feature/json.ts | 21 + .../src/builder/feature}/redirect.ts | 228 +- .../src/builder/feature/style/index.ts | 59 + .../builder/feature}/style/lessAliasPlugin.ts | 17 +- .../src/builder/feature}/style/lessRender.ts | 11 +- .../feature}/style/postcssTransformer.ts | 56 +- .../feature}/style/postcssUrlPlugin.ts | 23 +- .../src/builder/feature}/style/sassRender.ts | 22 +- .../builder/feature}/style/transformStyle.ts | 44 +- .../src/builder/feature}/style/utils.ts | 17 +- .../module-tools/src/builder/feature/swc.ts | 186 + .../src/builder/feature/terser.ts | 67 + .../module-tools/src/builder/index.ts | 17 +- packages/solutions/module-tools/src/cli.ts | 10 +- .../solutions/module-tools/src/command.ts | 23 +- .../module-tools/src/config/merge.ts | 29 +- .../module-tools/src/config/normalize.ts | 21 +- .../module-tools/src/config/schema.ts | 17 +- .../src/config/transformLegacyConfig.ts | 5 +- .../module-tools/src/config/valid.ts | 25 +- .../module-tools/src/constants/build.ts | 86 +- .../module-tools/src/constants/file.ts | 22 +- .../module-tools}/src/constants/loader.ts | 2 +- packages/solutions/module-tools/src/debug.ts | 9 + packages/solutions/module-tools/src/error.ts | 8 +- .../solutions/module-tools/src/hooks/build.ts | 5 +- .../solutions/module-tools/src/hooks/misc.ts | 9 +- packages/solutions/module-tools/src/index.ts | 2 + .../module-tools/src/locale/index.ts | 10 +- .../module-tools/src/types/command.ts | 6 +- .../module-tools/src/types/config/index.ts | 177 +- .../module-tools/src/types/config/style.ts | 92 +- .../solutions/module-tools/src/types/dts.ts | 18 +- .../module-tools/src/types/esbuild.ts | 141 + .../solutions/module-tools/src/types/index.ts | 2 + .../src/types/legacyConfig/output.ts | 8 +- .../solutions/module-tools/src/types/utils.ts | 12 - .../module-tools/src/utils/assert.ts | 21 + .../module-tools/src/utils/builder.ts | 92 +- .../module-tools/src/utils/common.ts | 2 +- .../module-tools/src/utils/context.ts | 10 - .../solutions/module-tools/src/utils/dts.ts | 112 +- .../solutions/module-tools/src/utils/hash.ts | 9 + .../solutions/module-tools/src/utils/index.ts | 11 + .../solutions/module-tools/src/utils/input.ts | 6 + .../module-tools/src/utils/language.ts | 9 - .../module-tools/src/utils/libuild-plugin.ts | 26 - .../module-tools/src/utils/map.ts} | 18 + .../solutions/module-tools/src/utils/path.ts | 6 - .../solutions/module-tools/src/utils/print.ts | 4 +- .../solutions/module-tools/src/utils/style.ts | 9 +- .../utils/{tspathsTransform.ts => tspath.ts} | 16 - .../module-tools/tests/builder.test.ts | 2 +- .../tests/fixtures/rollup/error/src/index.ts | 8 - ...Config.test.ts => generateDtsInfo.test.ts} | 19 +- .../module-tools/tests/mapValue.test.ts | 2 +- .../module-tools/tests/rollup.test.ts | 79 - .../module-tools/tests}/style/index.less | 0 .../tests}/style/less/absolute.less | 0 .../tests}/style/less/common.less | 0 .../tests}/style/less/variable.less | 0 .../tests/style/rebaseUrl.test.ts | 55 + .../module-tools/tests/tsconfig.json | 3 +- packages/solutions/module-tools/tsconfig.json | 20 +- .../solutions/module-tools/vitest.config.ts | 20 + pnpm-lock.yaml | 2283 +- pnpm-workspace.yaml | 1 - scripts/build/package.json | 2 - tests/integration/libuild/.eslintrc.cjs | 3 - tests/integration/libuild/.mocharc.js | 10 - tests/integration/libuild/README.md | 23 - .../configs/ignore-dts-files/index.test.ts | 16 - .../libuild/configs/ignore-dts-files/src/a.ts | 0 .../configs/ignore-dts-files/src/b.d.ts | 0 .../import-inexist-module/custom.test.ts | 29 - .../errors/import-inexist-module/error.js | 3 - .../errors/import-inexist-module/index.ts | 3 - .../assets/__snapshots__/asset.test.ts.snap | 16420 ---------- .../libuild/fixtures/assets/asset.test.ts | 70 - .../libuild/fixtures/assets/index.less | 3 - .../libuild/fixtures/assets/index.ts | 4 - .../libuild/fixtures/assets/modern.png | Bin 16400 -> 0 bytes .../libuild/fixtures/css/entrypoint/a-b.ts | 1 - .../libuild/fixtures/css/entrypoint/a.ts | 1 - .../fixtures/css/entrypoint/css-entry.test.ts | 18 - .../libuild/fixtures/css/entrypoint/index.css | 3 - .../import/__snapshots__/import.test.ts.snap | 21 - .../fixtures/css/import/import.test.ts | 18 - .../fixtures/css/module/index.module.css | 3 - .../fixtures/css/module/index.module.less | 7 - .../fixtures/css/module/index.module.sass | 7 - .../libuild/fixtures/css/module/index.ts | 7 - .../fixtures/css/module/module.spec.ts | 20 - .../__snapshots__/data-url.spec.ts.snap | 10 - .../fixtures/data-url/data-url.spec.ts | 11 - .../__snapshots__/resolve.spec.ts.snap | 14 - .../alias/secret.ts | 1 - .../enhanced-resolve-tsconfig-alias/index.ts | 5 - .../resolve.spec.ts | 30 - .../libuild/fixtures/env/dot-env/.env | 1 - .../libuild/fixtures/env/dot-env/.gitignore | 1 - .../dot-env/__snapshots__/env.test.ts.snap | 12 - .../libuild/fixtures/env/dot-env/env.test.ts | 15 - .../libuild/fixtures/env/dot-env/index.ts | 3 - .../fixtures/external/external.spec.ts | 26 - .../libuild/fixtures/external/index.tsx | 5 - .../cjs/__snapshots__/format.test.ts.snap | 71 - .../fixtures/format/cjs/format.test.ts | 22 - .../libuild/fixtures/format/cjs/index.ts | 3 - .../esm/__snapshots__/format.test.ts.snap | 23 - .../fixtures/format/esm/format.test.ts | 22 - .../libuild/fixtures/format/esm/index.ts | 3 - .../iife/__snapshots__/format.test.ts.snap | 21 - .../fixtures/format/iife/format.test.ts | 22 - .../libuild/fixtures/format/iife/index.ts | 3 - .../umd/__snapshots__/format.test.ts.snap | 27 - .../fixtures/format/umd/format.test.ts | 16 - .../libuild/fixtures/format/umd/index.ts | 3 - .../__snapshots__/globals.test.ts.snap | 41 - .../libuild/fixtures/globals/globals.test.ts | 16 - .../libuild/fixtures/globals/index.ts | 3 - .../libuild/fixtures/input/array/index.ts | 1 - .../fixtures/input/array/input.test.ts | 14 - .../fixtures/input/empty-object/empty.test.ts | 14 - .../libuild/fixtures/json/bundleless/index.js | 3 - .../fixtures/json/bundleless/json.test.ts | 18 - .../libuild/fixtures/json/bundleless/zh.json | 3 - .../fixtures/json/default-import/index.js | 3 - .../fixtures/json/default-import/json.test.ts | 17 - .../fixtures/json/default-import/zh.json | 3 - .../fixtures/json/named-import/index.js | 3 - .../fixtures/json/named-import/json.test.ts | 19 - .../fixtures/json/named-import/zh.json | 5 - .../jsx/__snapshots__/jsx.test.ts.snap | 8059 ----- .../libuild/fixtures/jsx/automatic.tsx | 3 - .../libuild/fixtures/jsx/default.tsx | 5 - .../libuild/fixtures/jsx/jsx.test.ts | 51 - .../basic/__snapshots__/basic.test.ts.snap | 9 - .../libuild/fixtures/less/basic/basic.less | 6 - .../libuild/fixtures/less/basic/basic.test.ts | 14 - .../__snapshots__/implementation.test.ts.snap | 17 - .../fixtures/less/implementation/basic.less | 6 - .../implementation/implementation.test.ts | 34 - .../import-css-duplicate.test.ts.snap | 27 - .../import-css-duplicate.test.ts | 22 - .../less/import-css-duplicate/index.css | 3 - .../less/import-css-duplicate/index.less | 5 - .../less/import-css-duplicate/index.ts | 2 - .../__snapshots__/import-css.test.ts.snap | 26591 ---------------- .../less/import-css/import-css.test.ts | 19 - .../fixtures/less/import-css/style/basic.css | 3 - .../fixtures/less/import-css/style/index.less | 3 - .../import/__snapshots__/import.test.ts.snap | 168 - .../fixtures/less/import/import.test.ts | 14 - .../__snapshots__/basic.test.ts.snap | 9 - .../fixtures/less/prependData/basic.less | 3 - .../fixtures/less/prependData/basic.test.ts | 19 - .../__snapshots__/less-url-asset.test.ts.snap | 12 - .../fixtures/less/url-asset/index.less | 7 - .../libuild/fixtures/less/url-asset/index.ts | 1 - .../less/url-asset/less-url-asset.test.ts | 11 - .../__snapshots__/func.test.ts.snap | 49 - .../fixtures/less/with-function/each.less | 43 - .../fixtures/less/with-function/func.test.ts | 25 - .../fixtures/less/with-function/range.less | 5 - .../libuild/fixtures/lodash/index.test.ts | 21 - .../libuild/fixtures/lodash/src/index.ts | 8 - .../libuild/fixtures/metafile/index.ts | 3 - .../fixtures/metafile/metafile.test.ts | 16 - .../__snapshots__/minify.test.ts.snap | 6 - .../minify/esbuild-target-es6/index.ts | 2 - .../minify/esbuild-target-es6/minify.test.ts | 18 - .../__snapshots__/esbuild.test.ts.snap | 6 - .../fixtures/minify/esbuild/esbuild.test.ts | 15 - .../libuild/fixtures/minify/esbuild/index.ts | 2 - .../false/__snapshots__/false.test.ts.snap | 9 - .../fixtures/minify/false/false.test.ts | 14 - .../libuild/fixtures/minify/false/index.ts | 2 - .../__snapshots__/terser.test.ts.snap | 3 - .../minify/terser-target-es6/index.ts | 2 - .../minify/terser-target-es6/terser.test.ts | 17 - .../terser/__snapshots__/terser.test.ts.snap | 3 - .../libuild/fixtures/minify/terser/index.ts | 2 - .../fixtures/minify/terser/terser.test.ts | 16 - .../libuild/fixtures/modules/mixin/answer.ts | 1 - .../libuild/fixtures/modules/mixin/index.ts | 5 - tests/integration/libuild/fixtures/name/a.css | 3 - .../libuild/fixtures/name/index.ts | 4 - .../libuild/fixtures/name/other.ts | 3 - .../libuild/fixtures/name/output.spec.ts | 23 - .../libuild/fixtures/name/share.ts | 1 - .../fixtures/no-bundle/no-bundle.test.ts | 21 - .../libuild/fixtures/no-bundle/src/index.less | 3 - .../fixtures/no-bundle/src/index.module.less | 3 - .../libuild/fixtures/no-bundle/src/index.ts | 6 - .../libuild/fixtures/no-bundle/src/logo.png | Bin 101506 -> 0 bytes .../libuild/fixtures/node-enhanced/buildin.ts | 5 - .../fixtures/node-enhanced/external.d.ts | 1 - .../fixtures/node-enhanced/external.ts | 5 - .../libuild/fixtures/node-enhanced/inner.ts | 1 - .../node-enhanced/node-enhanced.spec.ts | 34 - .../libuild/fixtures/node-enhanced/normal.ts | 3 - .../fixtures/platform/browser-test/http.js | 1 - .../fixtures/platform/browser-test/index.d.ts | 1 - .../fixtures/platform/browser-test/index.js | 2 - .../platform/browser-test/package.json | 16 - .../fixtures/platform/browser-test/xhr.js | 1 - .../libuild/fixtures/platform/browser.ts | 2 - .../libuild/fixtures/platform/node.ts | 5 - .../fixtures/platform/platform.spec.ts | 31 - .../postcss/autoModules/auto-modules.test.ts | 30 - .../fixtures/postcss/autoModules/index.css | 6 - .../__snapshots__/config-file.test.ts.snap | 12 - .../postcss/config-file/config-file.test.ts | 14 - .../fixtures/postcss/config-file/index.css | 6 - .../postcss/config-file/postcss.config.js | 23 - .../redirect/disable-redirect.test.ts | 29 - .../fixtures/redirect/redirect.test.ts | 27 - .../libuild/fixtures/redirect/src/style.ts | 5 - .../__snapshots__/protocol.test.ts.snap | 11 - .../resolve-node-protocol/protocol.test.ts | 13 - .../resolve-with-condition-exports/.gitignore | 1 - ...esolve-with-condition-exports.spec.ts.snap | 91 - .../resolve-with-condition-exports.spec.ts | 32 - .../resolve-with-mainFields/.gitignore | 1 - .../resolve-with-mainFields.spec.ts.snap | 10 - .../resolve-with-mainFields.spec.ts | 14 - .../__snapshots__/resolve.spec.ts.snap | 27 - .../libuild/fixtures/resolve/alias/secret.ts | 1 - .../libuild/fixtures/resolve/false.ts | 2 - .../libuild/fixtures/resolve/index.ts | 5 - .../libuild/fixtures/resolve/other.ts | 2 - .../libuild/fixtures/resolve/resolve.spec.ts | 75 - .../libuild/fixtures/resolve/tsconfig.json | 9 - .../basic/__snapshots__/basic.test.ts.snap | 9 - .../libuild/fixtures/sass/basic/basic.scss | 7 - .../libuild/fixtures/sass/basic/basic.test.ts | 14 - .../__snapshots__/implementation.test.ts.snap | 17 - .../fixtures/sass/implementation/basic.scss | 7 - .../implementation/implementation.test.ts | 34 - .../import/__snapshots__/import.test.ts.snap | 168 - .../libuild/fixtures/sass/import/import.scss | 2 - .../fixtures/sass/import/import.test.ts | 14 - .../__snapshots__/basic.test.ts.snap | 9 - .../fixtures/sass/prependData/basic.scss | 5 - .../fixtures/sass/prependData/basic.test.ts | 20 - .../url/__snapshots__/sass-url.test.ts.snap | 12 - .../libuild/fixtures/sass/url/index.scss | 7 - .../fixtures/sass/url/sass-url.test.ts | 14 - .../sideEffects/antd-mobile/src/global.js | 1 - .../sideEffects/antd-mobile/src/index.js | 1 - .../libuild/fixtures/sideEffects/config.ts | 4 - .../libuild/fixtures/sideEffects/index.ts | 3 - .../libuild/fixtures/sideEffects/other.ts | 4 - .../fixtures/sideEffects/sideeffect.test.ts | 75 - .../sourcemap/external/external.test.ts | 16 - .../fixtures/sourcemap/external/index.ts | 5 - .../fixtures/sourcemap/false/false.test.ts | 16 - .../libuild/fixtures/sourcemap/false/index.ts | 5 - .../fixtures/sourcemap/inline/index.ts | 6 - .../fixtures/sourcemap/inline/inline.test.ts | 120 - .../libuild/fixtures/sourcemap/true/index.ts | 5 - .../fixtures/sourcemap/true/true.test.ts | 17 - .../cjs/__snapshots__/splitting.test.ts.snap | 20 - .../libuild/fixtures/splitting/cjs/dynamic.ts | 3 - .../libuild/fixtures/splitting/cjs/index.ts | 3 - .../splitting/cjs/lib/dynamic-2A63DP2P.js | 7 - .../fixtures/splitting/cjs/lib/index.js | 4 - .../fixtures/splitting/cjs/splitting.test.ts | 13 - .../esm/__snapshots__/splitting.test.ts.snap | 20 - .../libuild/fixtures/splitting/esm/dynamic.ts | 3 - .../libuild/fixtures/splitting/esm/index.ts | 3 - .../fixtures/splitting/esm/splitting.test.ts | 13 - .../libuild/fixtures/stage/index.ts | 1 - .../libuild/fixtures/stage/stage.spec.ts | 38 - .../libuild/fixtures/style-inject/index.css | 3 - .../libuild/fixtures/style-inject/inject.tsx | 6 - .../style-inject/style-inject.test.ts | 21 - .../target/__snapshots__/target.test.ts.snap | 191 - .../libuild/fixtures/target/index.ts | 6 - .../libuild/fixtures/target/target.test.ts | 40 - .../__snapshots__/treeshaking.test.ts.snap | 10 - .../libuild/fixtures/treeshaking/index.ts | 3 - .../fixtures/treeshaking/mylib/src/exports.ts | 3 - .../fixtures/treeshaking/mylib/src/index.ts | 1 - .../fixtures/treeshaking/mylib/src/lib.ts | 2 - .../fixtures/treeshaking/treeshaking.test.ts | 15 - tests/integration/libuild/fixtures/types.d.ts | 19 - .../libuild/fixtures/virtual-module/index.ts | 2 - .../libuild/fixtures/virtual-module/raw.ts | 1 - .../fixtures/virtual-module/virtual.spec.ts | 39 - .../fixtures/watch/basic/basic.test.ts | 36 - .../libuild/fixtures/watch/basic/index.ts | 0 .../fixtures/watch/changed/changed.test.ts | 30 - .../libuild/fixtures/watch/changed/index.ts | 0 .../fixtures/watch/error/error.test.ts | 32 - .../libuild/fixtures/watch/error/index.ts | 0 .../fixtures/watch/first-bundle/error.test.ts | 68 - .../fixtures/watch/first-bundle/index.ts | 0 tests/integration/libuild/package.json | 54 - .../babel/__snapshots__/babel.test.ts.snap | 8 - .../libuild/plugins/babel/babel.test.ts | 19 - .../libuild/plugins/babel/index.ts | 2 - .../libuild/plugins/node-polyfill/index.ts | 3 - .../plugins/node-polyfill/polyfill.test.ts | 17 - .../svgr/__snapshots__/svgr.test.ts.snap | 40 - .../libuild/plugins/svgr/src/index.ts | 3 - .../libuild/plugins/svgr/svgr.test.ts | 34 - .../libuild/plugins/svgr/types.d.ts | 4 - .../swc/__snapshots__/swc.test.ts.snap | 237 - .../integration/libuild/plugins/swc/index.tsx | 21 - .../libuild/plugins/swc/swc.test.ts | 82 - tests/integration/libuild/toolkit/expect.ts | 8 - tests/integration/libuild/toolkit/index.ts | 3 - .../libuild/toolkit/libuilderTest.ts | 85 - .../libuild/toolkit/waitForEqual.ts | 20 - tests/integration/libuild/tsconfig.json | 11 - .../module/fixtures/build/alias/alias.test.ts | 84 + .../build/alias/js/function.config.ts} | 2 +- .../build/alias/js/object.config.ts} | 2 +- .../build}/alias/js/package.json | 0 .../build}/alias/js/src/b.js | 0 .../build}/alias/js/src/index.js | 0 .../build/alias/ts/function.config.ts} | 2 +- .../build/alias/ts/modern.config.ts} | 5 +- .../build/alias/ts/object.config.ts} | 2 +- .../build}/alias/ts/package.json | 0 .../module/fixtures/build/alias/ts}/src/b.ts | 0 .../fixtures/build/alias/ts}/src/index.ts | 0 .../fixtures/build/alias/ts}/tsconfig.json | 0 .../module/fixtures/build/asset/asset.test.ts | 107 + .../build/asset/limit/modern.config.ts | 11 + .../fixtures/build/asset/limit/package.json | 7 + .../build/asset/limit}/src/index.js | 0 .../fixtures/build/asset/limit/src}/logo.svg | 0 .../build}/asset/path/package.json | 0 .../build/asset/path}/path.bundle.config.ts | 0 .../asset/path}/path.bundleless.config.ts | 0 .../build}/asset/path/src/a.png | 0 .../build}/asset/path/src/index.jsx | 0 .../build/asset/publicPath/modern.config.ts | 12 + .../build/asset/publicPath/package.json | 7 + .../build/asset/publicPath/src/index.js | 3 + .../build/asset/publicPath}/src/logo.svg | 0 .../build/asset/svgr/bundle.config.ts} | 2 +- .../build/asset}/svgr/bundleless.config.ts | 0 .../build/asset}/svgr/exclude.config.ts | 0 .../build/asset}/svgr/package.json | 0 .../fixtures/build/asset/svgr/src/index.js | 3 + .../fixtures/build/asset/svgr/src}/logo.svg | 0 .../build/autoExternal}/autoExternal.test.ts | 4 +- .../build}/autoExternal/config.ts | 0 .../build}/autoExternal/package.json | 0 .../build}/autoExternal/src/env.d.ts | 0 .../build}/autoExternal/src/index.ts | 0 .../build/banner-footer/banner.test.ts | 52 + .../build/banner-footer/bundle.config.ts | 18 + .../build/banner-footer/bundleless.config.ts | 18 + .../fixtures/build/banner-footer/package.json | 4 + .../build/banner-footer/src/index.css | 3 + .../fixtures/build/banner-footer/src/index.ts | 3 + .../build/banner-footer}/tsconfig.json | 0 .../build/buildType}/buildType.test.ts | 6 +- .../build}/buildType/bundle.config.ts | 0 .../build}/buildType/bundleless.config.ts | 0 .../build}/buildType/package.json | 0 .../build/buildType}/src/index.js | 0 .../build/buildType}/src/utils.js | 0 .../build}/copy/config-1.ts | 0 .../{src => fixtures/build/copy}/copy.test.ts | 4 +- .../build}/copy/package.json | 0 .../build}/copy/src/index.html | 0 .../build}/copy/src/test.txt | 0 .../build}/copy/temp-1/a.png | 0 .../build}/copy/temp-2/a.png | 0 .../build}/copy/temp-3/a.png | 0 .../build}/copy/temp-3/b.txt | 0 .../build}/copy/temp-4/index.html | 0 .../__snapshots__/decorator.test.ts.snap | 3 +- .../build/decorator}/decorator.test.ts | 7 +- .../build}/decorator/modern.config.ts | 4 +- .../build}/decorator/package.json | 0 .../build}/decorator/src/index.ts | 0 .../build/define/define.test.ts} | 27 +- .../build/define}/js/bundle.config.ts | 0 .../build/define}/js/bundleless.config.ts | 0 .../build/define}/js/package.json | 0 .../build/define}/js/src/index.js | 0 .../build/define}/ts/bundle.config.ts | 0 .../build/define}/ts/bundleless.config.ts | 0 .../build/define}/ts/package.json | 0 .../build/define}/ts/src/env.d.ts | 0 .../build/define}/ts/src/index.ts | 0 .../build/define/ts}/tsconfig.json | 5 +- .../build}/dts/abortOnError-bundle.ts | 2 +- .../build}/dts/abortOnError-bundleless.ts | 2 +- .../build}/dts/distPath-bundle.ts | 0 .../build}/dts/distPath-bundleless.ts | 0 .../{src => fixtures/build/dts}/dts.test.ts | 20 +- .../build}/dts/false-bundle.ts | 0 .../build}/dts/false-bundleless.ts | 0 .../build}/dts/only-bundle.ts | 0 .../build}/dts/only-bundleless.ts | 0 .../build}/dts/package.json | 0 .../build}/dts/src-error/index.ts | 0 .../module/fixtures/build/dts}/src/b.ts | 0 .../ts => fixtures/build/dts}/src/index.ts | 0 .../ts/src => fixtures/build/dts/src1}/b.ts | 0 .../build}/dts/src1/index.ts | 0 .../dts/src => fixtures/build/dts/src2}/b.ts | 0 .../build}/dts/src2/index.ts | 0 .../build}/dts/tsconfig-bundle.json | 0 .../build}/dts/tsconfig-bundleless.json | 0 .../build}/dts/tsconfig-error.json | 0 .../module/fixtures/build/dts}/tsconfig.json | 0 .../build}/dts/tsconfigPath-bundle.ts | 0 .../build}/dts/tsconfigPath-bundleless.ts | 4 +- .../esbuildOptions}/esbuildOptions.test.ts | 5 +- .../build}/esbuildOptions/modern.config.ts | 0 .../build}/esbuildOptions/package.json | 0 .../build}/esbuildOptions/src/index.ts | 0 .../build}/externals/config.ts | 0 .../build/externals}/externals.test.ts | 4 +- .../build}/externals/package.json | 0 .../build/externals}/src/common.ts | 0 .../build}/externals/src/index.ts | 0 .../format}/__snapshots__/format.test.ts.snap | 64 +- .../build}/format/cjs-bundle.config.ts | 0 .../build}/format/cjs-bundleless.config.ts | 0 .../build}/format/cjs/package.json | 0 .../build}/format/cjs/src/index.js | 0 .../build}/format/cjs/src/utils.js | 0 .../build}/format/esm-bundle.config.ts | 0 .../build}/format/esm-bundleless.config.ts | 0 .../build}/format/esm/package.json | 0 .../build}/format/esm/src/index.js | 0 .../build}/format/esm/src/utils.js | 0 .../build/format}/format.test.ts | 27 +- .../build}/format/iife-bundle.config.ts | 0 .../build}/format/iife-bundleless.config.ts | 0 .../build}/format/iife/package.json | 0 .../build}/format/iife/src/index.js | 0 .../build}/format/iife/src/utils.js | 0 .../build}/format/umd-bundle.config.ts | 0 .../build}/format/umd-bundleless.config.ts | 0 .../build}/format/umd/package.json | 0 .../build}/format/umd/src/index.js | 0 .../build}/format/umd/src/utils.js | 0 .../entry => fixtures/build/input}/array.ts | 0 .../build/input/input.test.ts} | 36 +- .../build/input}/modern.config.ts | 0 .../entry => fixtures/build/input}/object.ts | 0 .../build/input}/package.json | 0 .../build/input}/src/browser.ts | 0 .../build/input}/src/common.ts | 0 .../build/input}/src/index.a.ts | 0 .../build/input}/src/index.ts | 0 .../ts => fixtures/build/input}/tsconfig.json | 0 .../build/jsx/automatic.config.ts} | 2 +- .../module/fixtures/build/jsx/jsx.test.ts | 47 + .../build}/jsx/package.json | 0 .../fixtures/build/jsx/preserve.config.ts | 9 + .../build}/jsx/src/index.jsx | 0 .../build/jsx/transform.config.ts} | 2 +- .../build}/metafile/config.ts | 0 .../build/metafile}/metafile.test.ts | 4 +- .../build}/metafile/package.json | 0 .../build}/metafile/src/common.ts | 0 .../build}/metafile/src/index.ts | 0 .../build}/minify/config.ts | 0 .../build/minify}/minify.test.ts | 4 +- .../build}/minify/package.json | 0 .../build}/minify/src/common.ts | 0 .../build}/minify/src/index.ts | 0 .../build}/platform/browser.ts | 0 .../build}/platform/node.ts | 0 .../build}/platform/package.json | 0 .../build/platform}/platform.test.ts | 7 +- .../build}/platform/src/common.ts | 0 .../build}/platform/src/index.ts | 0 .../build}/redirect/no-redirect.ts | 0 .../build}/redirect/package.json | 0 .../fixtures/build/redirect/redirect.test.ts | 52 + .../build}/redirect/redirect.ts | 1 + .../fixtures/build/redirect/src/alias.ts | 3 + .../build/redirect/src/index.module.css} | 2 +- .../fixtures/build/redirect/src/index.ts | 5 + .../fixtures/build/redirect/src}/logo.svg | 0 .../fixtures/build/redirect}/tsconfig.json | 5 +- .../build/resolve/data-url/dataurl.test.ts | 14 + .../fixtures/build/resolve}/data-url/index.ts | 1 + .../build/resolve/data-url/modern.config.ts} | 0 .../build/resolve/data-url/package.json | 4 + .../build/resolve/node-protocol}/index.ts | 0 .../resolve/node-protocol/modern.config.ts | 3 + .../build/resolve/node-protocol/package.json | 4 + .../resolve/node-protocol/protocol.test.ts | 14 + .../resolve/with-condition-exports/.gitignore | 2 + .../resolve/with-condition-exports}/entry1.ts | 0 .../resolve/with-condition-exports}/entry2.ts | 0 .../resolve/with-condition-exports/entry3.ts} | 3 +- .../resolve/with-condition-exports/entry4.ts} | 0 .../modern-node.config.ts | 12 + .../with-condition-exports/modern.config.ts | 13 + .../node_modules/lib1/package.json | 0 .../node_modules/lib1/src/index.cjs | 0 .../node_modules/lib1/src/index.mjs | 0 .../node_modules/lib2/package.json | 0 .../node_modules/lib2/src/index.cjs | 0 .../node_modules/lib2/src/index.mjs | 0 .../node_modules/lib2/src/module.js | 0 .../node_modules/lib3/package.json | 0 .../node_modules/lib3/src/browser.js | 0 .../node_modules/lib3/src/node.js | 0 .../with-condition-exports/package.json | 4 + .../resolve-with-condition-exports.test.ts | 45 + .../resolve/with-js-extensions/example.mts | 1 + .../build/resolve/with-js-extensions/index.ts | 3 + .../with-js-extensions/modern.config.ts | 13 + .../resolve/with-js-extensions/package.json | 4 + .../resolve-with-js-extensions.test.ts | 14 + .../build/resolve/with-mainFields/.gitignore | 2 + .../build/resolve/with-mainFields/entry1.ts} | 0 .../build/resolve/with-mainFields/entry2.ts | 3 + .../resolve/with-mainFields/modern.config.ts | 26 + .../node_modules/lib1/package.json | 0 .../node_modules/lib1/src/index.ts | 0 .../node_modules/lib2}/package.json | 12 +- .../node_modules/lib2/src/browser.ts | 1 + .../node_modules/lib2/src/main.ts | 1 + .../resolve/with-mainFields/package.json | 4 + .../resolve-with-mainFields.test.ts | 26 + .../build}/sideEffects/index.css | 0 .../build}/sideEffects/index.ts | 0 .../build/sideEffects/modern.config.ts} | 0 .../build}/sideEffects/package.json | 0 .../build/sideEffects}/sideEffects.test.ts | 10 +- .../build}/sourceDir/config.ts | 0 .../build}/sourceDir/lib/browser.js | 0 .../build}/sourceDir/lib/common.js | 0 .../build}/sourceDir/lib/index.js | 0 .../build}/sourceDir/package.json | 0 .../build/sourceDir}/sourceDir.test.ts | 4 +- .../__snapshots__/sourceMap.test.ts.snap} | 4 +- .../build/sourceMap}/external.ts | 0 .../build/sourceMap}/false.ts | 0 .../build/sourceMap}/inline.ts | 0 .../build/sourceMap}/package.json | 0 .../build/sourceMap/sourceMap.test.ts} | 4 +- .../build/sourceMap}/src/index.js | 0 .../build/sourceMap}/src/utils.js | 0 .../build/sourceMap}/true.ts | 0 .../fixtures/build/splitting/cjs.config.ts | 11 + .../build}/splitting/config.ts | 0 .../build}/splitting/package.json | 0 .../build/splitting}/splitting.test.ts | 14 +- .../build}/splitting/src/common.ts | 0 .../build}/splitting/src/index.ts | 0 .../fixtures/build/style/css}/import.css | 9 +- .../fixtures/build/style/css/import.test.ts | 16 + .../fixtures/build/style/css}/lib1.css | 0 .../fixtures/build/style/css}/lib2.css | 0 .../build/style/css/modern.config.ts} | 4 +- .../build/style/css}/package.json | 2 +- .../fixtures/build/style/less/.gitignore | 2 + .../build/style/less}/assets/normal.ttf | Bin .../build/style/less/import.config.ts | 9 + .../style}/less/import/extension/index.less | 0 .../style}/less/import/extension/util.less | 0 .../style}/less/import/foundation/code.less | 0 .../build/style}/less/import/index.less | 2 +- .../build/style}/less/import/index.ts | 2 +- .../build/style}/less/import/prefer/index.js | 0 .../style}/less/import/prefer/index.less | 0 .../fixtures/build/style/less/index.less | 15 + .../fixtures/build/style/less/less.test.ts | 30 + .../build/style/less/modern.config.ts | 20 + .../fixtures/build/style/less/nest}/alias.css | 0 .../fixtures/build/style/less}/nest/nest.less | 0 .../style/less/node_modules/lib1/index.css | 3 + .../less/node_modules/lib1}/package.json | 8 +- .../fixtures/build/style/less/package.json | 4 + .../fixtures/build/style/others/index.js | 3 + .../build/style/others/modern.config.ts | 16 + .../fixtures/build/style/others/package.json | 4 + .../fixtures/build/style/others/style.css | 3 + .../fixtures/build/style/others/style.test.ts | 23 + .../build/style/postcss/modern.config.ts | 24 + .../fixtures/build/style/postcss/package.json | 7 + .../build/style/postcss/postcss.test.ts | 29 + .../build/style/postcss}/style.css | 0 .../fixtures/build/style/sass/.gitignore | 2 + .../build/style/sass}/foundation/_code.scss | 0 .../build/style/sass}/foundation/_lists.scss | 0 .../build/style/sass/foundation}/index.scss | 0 .../build/style/sass/foundation}/logo.svg | 0 .../fixtures/build/style/sass/index.scss | 14 + .../build/style/sass/modern.config.ts | 17 + .../style/sass/node_modules/lib1/index.css | 3 + .../style/sass/node_modules/lib1/package.json | 11 + .../fixtures/build/style/sass/package.json | 4 + .../fixtures/build/style/sass/scss.test.ts | 18 + .../tailwindcss/design-system.config.ts} | 10 +- .../build/style/tailwindcss/modern.config.ts | 32 + .../build/style/tailwindcss/package.json | 4 + .../build/style/tailwindcss/style.css} | 0 .../style/tailwindcss/tailwindcss.test.ts | 41 + .../build/target/es5.config.ts} | 3 +- .../build}/target/package.json | 0 .../module/fixtures/build/target/src/index.js | 3 + .../fixtures/build/target/target.test.ts | 20 + .../build/transformImport/modern.config.ts | 19 + .../build/transformImport/package.json | 7 + .../build/transformImport/src/index.ts | 3 + .../transformImport/transformImport.test.ts | 21 + .../build}/transformLodash/modern.config.ts | 0 .../build}/transformLodash/package.json | 0 .../build}/transformLodash/src/a.js | 0 .../build}/transformLodash/src/b.js | 0 .../transformLodash}/transformLodash.test.ts | 4 +- .../fixtures/build/tsconfig/modern.config.ts | 9 + .../fixtures/build/tsconfig/package.json | 4 + .../src1 => fixtures/build/tsconfig/src}/b.ts | 0 .../build/tsconfig}/src/index.ts | 2 +- .../build/tsconfig/tsconfig-test.json} | 2 +- .../fixtures/build/tsconfig/tsconfig.test.ts | 15 + .../__snapshots__/umdGlobals.test.ts.snap | 126 +- .../build}/umdGlobals/config.ts | 0 .../build}/umdGlobals/package.json | 0 .../build}/umdGlobals/src/common.js | 0 .../build}/umdGlobals/src/index.js | 0 .../build/umdGlobals}/umdGlobals.test.ts | 4 +- .../build}/umdModuleName/config.ts | 0 .../build}/umdModuleName/package.json | 0 .../build}/umdModuleName/src/common.js | 0 .../build}/umdModuleName/src/index.js | 0 .../umdModuleName}/umdModuleName.test.ts | 4 +- .../integration/module/fixtures/constants.ts | 7 + .../{src => }/fixtures/dev/before-dev-menu.ts | 0 .../fixtures/dev/config-with-plugin.ts | 0 .../fixtures/dev/config-with-plugins.ts | 0 .../module/{src => }/fixtures/dev/config.ts | 0 .../module/{src => fixtures/dev}/dev.test.ts | 4 +- .../{src => }/fixtures/dev/package.json | 0 .../module/{src => }/fixtures/dev/plugin-1.ts | 0 .../module/{src => }/fixtures/dev/plugin-2.ts | 0 .../module/{src => }/fixtures/dev/plugin-3.ts | 0 .../function => fixtures/dev}/src/index.js | 0 .../string => fixtures/dev}/src/utils.js | 0 .../platform}/buildPlatform.test.ts | 4 +- .../platform}/config-with-plugin.ts | 0 .../platform}/config-with-plugin2.ts | 0 .../platform}/config-with-plugins-1.ts | 0 .../platform}/config-with-plugins.ts | 0 .../module/fixtures/platform/config.ts | 3 + .../platform}/package.json | 0 .../platform}/plugin-1.ts | 0 .../platform}/plugin-2.ts | 0 .../platform}/plugin-3.ts | 0 .../platform}/plugin-4.ts | 0 .../platform}/plugin-5.ts | 0 .../platform}/plugin-6.ts | 0 .../string => fixtures/platform}/src/index.js | 0 .../platform}/src/utils.js | 0 .../preset}/buildPreset.test.ts | 4 +- .../preset}/error-1.config.ts | 0 .../preset}/error-2.config.ts | 0 .../preset}/error-3.config.ts | 0 .../preset}/error/package.json | 0 .../preset/error}/src/index.js | 0 .../preset/error}/src/utils.js | 0 .../preset}/extend-preset.config.ts | 0 .../preset}/function.config.ts | 0 .../preset}/function/package.json | 0 .../preset/function}/src/index.js | 0 .../preset}/function/src/utils.js | 0 .../preset}/package.json | 0 .../preset}/string.config.ts | 0 .../preset}/string/package.json | 0 .../preset/string}/src/index.js | 0 .../preset/string}/src/utils.js | 0 .../module/{src => fixtures}/utils.ts | 9 +- tests/integration/module/package.json | 15 +- .../module/plugins/babel/babel.test.ts | 20 + .../module/plugins/babel/modern.config.ts | 14 + .../module/plugins/babel/package.json | 7 + .../module/plugins/babel/src/index.js | 3 + .../plugins/node-polyfill/modern.config.ts | 6 + .../node-polyfill/node-polyfill.test.ts | 20 + .../module/plugins/node-polyfill/package.json | 4 + .../module/plugins/node-polyfill/src/index.js | 1 + .../module/plugins/polyfill/modern.config.ts | 17 + .../module/plugins/polyfill/package.json | 4 + .../module/plugins/polyfill/polyfill.test.ts | 20 + .../module/plugins/polyfill/src/index.ts | 1 + .../src/__snapshots__/alias.test.ts.snap | 113 - .../__snapshots__/designSystem.test.ts.snap | 18 - .../__snapshots__/esbuildOptions.test.ts.snap | 34 - tests/integration/module/src/alias.test.ts | 184 - tests/integration/module/src/asset.test.ts | 44 - tests/integration/module/src/constants.ts | 16 - .../module/src/designSystem.test.ts | 48 - .../alias/js/bundleless-function.config.ts | 14 - .../alias/js/bundleless-object.config.ts | 12 - .../alias/ts/bundleless-function.config.ts | 14 - .../alias/ts/bundleless-object.config.ts | 11 - .../fixtures/designSystem/bundle.config.ts | 14 - .../src/fixtures/designSystem/package.json | 4 - .../module/src/fixtures/dts/src2/b.ts | 2 - .../src/fixtures/inputFilter/package.json | 4 - .../src/fixtures/inputFilter/src/index.ts | 3 - .../jsx/automatic-bundleless.config.ts | 9 - .../jsx/transform-bundleless.config.ts | 9 - .../module/src/fixtures/redirect/src/index.ts | 3 - .../module/src/fixtures/target/src/index.js | 3 - .../module/src/fixtures/target/src/utils.js | 1 - .../module/src/fixtures/tools/config.ts | 12 - .../src/fixtures/tools/postcss-plugin.js | 13 - .../module/src/fixtures/tools/src/index.js | 1 - .../src/fixtures/utils/builder/package.json | 7 - .../module/src/fixtures/watch/package.json | 4 - .../module/src/fixtures/watch/src/index.js | 3 - .../module/src/fixtures/watch/src/utils.js | 1 - .../module/src/inputFilter.test.ts | 37 - tests/integration/module/src/jsx.test.ts | 80 - tests/integration/module/src/redirect.test.ts | 35 - tests/integration/module/src/svgr.test.ts | 46 - tests/integration/module/src/target.test.ts | 20 - tests/integration/module/src/tools.test.ts | 25 - tests/jest-ut.config.js | 1 - tests/jest.config.js | 1 - 924 files changed, 6068 insertions(+), 65570 deletions(-) create mode 100644 .changeset/quick-plums-heal.md create mode 100644 .changeset/soft-experts-roll.md delete mode 100644 packages/libuild/libuild-core/.eslintrc.cjs delete mode 100644 packages/libuild/libuild-core/.gitignore delete mode 100644 packages/libuild/libuild-core/.mocharc.js delete mode 100644 packages/libuild/libuild-core/CHANGELOG.md delete mode 100644 packages/libuild/libuild-core/LICENSE.md delete mode 100644 packages/libuild/libuild-core/README.md delete mode 100644 packages/libuild/libuild-core/api-extractor.json delete mode 100644 packages/libuild/libuild-core/package.json delete mode 100644 packages/libuild/libuild-core/scripts/build.ts delete mode 100644 packages/libuild/libuild-core/src/bundler/adapter.ts delete mode 100644 packages/libuild/libuild-core/src/bundler/index.ts delete mode 100644 packages/libuild/libuild-core/src/bundler/resolve.ts delete mode 100644 packages/libuild/libuild-core/src/constants/config.ts delete mode 100644 packages/libuild/libuild-core/src/constants/error.ts delete mode 100644 packages/libuild/libuild-core/src/constants/plugins.ts delete mode 100644 packages/libuild/libuild-core/src/constants/regExp.ts delete mode 100644 packages/libuild/libuild-core/src/core/index.ts delete mode 100644 packages/libuild/libuild-core/src/core/resolve.ts delete mode 100644 packages/libuild/libuild-core/src/core/transform.ts delete mode 100644 packages/libuild/libuild-core/src/error/error.ts delete mode 100644 packages/libuild/libuild-core/src/error/failure.ts delete mode 100644 packages/libuild/libuild-core/src/error/index.ts delete mode 100644 packages/libuild/libuild-core/src/error/utils.ts delete mode 100644 packages/libuild/libuild-core/src/index.ts delete mode 100644 packages/libuild/libuild-core/src/logger.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/asset.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/format-cjs.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/getInternalPlugin.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/json.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/metafile.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/minify.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/resolve.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/style/index.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/watch.ts delete mode 100644 packages/libuild/libuild-core/src/plugins/write-file.ts delete mode 100644 packages/libuild/libuild-core/src/types/builder.ts delete mode 100644 packages/libuild/libuild-core/src/types/callback.ts delete mode 100644 packages/libuild/libuild-core/src/types/config/asset.ts delete mode 100644 packages/libuild/libuild-core/src/types/config/index.ts delete mode 100644 packages/libuild/libuild-core/src/types/config/resolve.ts delete mode 100644 packages/libuild/libuild-core/src/types/config/style.ts delete mode 100644 packages/libuild/libuild-core/src/types/error.ts delete mode 100644 packages/libuild/libuild-core/src/types/global.d.ts delete mode 100644 packages/libuild/libuild-core/src/types/index.ts delete mode 100644 packages/libuild/libuild-core/src/types/logger.ts delete mode 100644 packages/libuild/libuild-core/src/utils/index.ts delete mode 100644 packages/libuild/libuild-core/src/utils/normalizeConfig.ts delete mode 100644 packages/libuild/libuild-core/src/utils/normalizeSourceMap.ts delete mode 100644 packages/libuild/libuild-core/test/dts/define-config.test-d.ts delete mode 100644 packages/libuild/libuild-core/test/dts/exist.test-d.ts delete mode 100644 packages/libuild/libuild-core/test/unit/findEntry.test.ts delete mode 100644 packages/libuild/libuild-core/test/unit/getAllDep.test.ts delete mode 100644 packages/libuild/libuild-core/test/unit/style/rebaseUrl.test.ts delete mode 100644 packages/libuild/libuild-core/tsconfig.build.json delete mode 100644 packages/libuild/libuild-core/tsconfig.json delete mode 100644 packages/libuild/libuild-plugin-babel/.eslintrc.cjs delete mode 100644 packages/libuild/libuild-plugin-babel/CHANGELOG.md delete mode 100644 packages/libuild/libuild-plugin-babel/README.md delete mode 100644 packages/libuild/libuild-plugin-babel/modern.config.js delete mode 100644 packages/libuild/libuild-plugin-babel/package.json delete mode 100644 packages/libuild/libuild-plugin-babel/src/index.ts delete mode 100644 packages/libuild/libuild-plugin-babel/tsconfig.json delete mode 100644 packages/libuild/libuild-plugin-node-polyfill/.eslintrc.cjs delete mode 100644 packages/libuild/libuild-plugin-node-polyfill/CHANGELOG.md delete mode 100644 packages/libuild/libuild-plugin-node-polyfill/README.md delete mode 100644 packages/libuild/libuild-plugin-node-polyfill/modern.config.js delete mode 100644 packages/libuild/libuild-plugin-node-polyfill/package.json delete mode 100644 packages/libuild/libuild-plugin-node-polyfill/src/index.ts delete mode 100644 packages/libuild/libuild-plugin-node-polyfill/tsconfig.json delete mode 100644 packages/libuild/libuild-plugin-svgr/.eslintrc.cjs delete mode 100644 packages/libuild/libuild-plugin-svgr/CHANGELOG.md delete mode 100644 packages/libuild/libuild-plugin-svgr/README.md delete mode 100644 packages/libuild/libuild-plugin-svgr/modern.config.js delete mode 100644 packages/libuild/libuild-plugin-svgr/package.json delete mode 100644 packages/libuild/libuild-plugin-svgr/src/index.ts delete mode 100644 packages/libuild/libuild-plugin-svgr/tsconfig.json delete mode 100644 packages/libuild/libuild-plugin-swc/.eslintrc.cjs delete mode 100644 packages/libuild/libuild-plugin-swc/CHANGELOG.md delete mode 100644 packages/libuild/libuild-plugin-swc/package.json delete mode 100644 packages/libuild/libuild-plugin-swc/scripts/build.ts delete mode 100644 packages/libuild/libuild-plugin-swc/src/constants.ts delete mode 100644 packages/libuild/libuild-plugin-swc/src/es5.ts delete mode 100644 packages/libuild/libuild-plugin-swc/src/index.ts delete mode 100644 packages/libuild/libuild-plugin-swc/src/legacy.ts delete mode 100644 packages/libuild/libuild-plugin-swc/src/transform.ts delete mode 100644 packages/libuild/libuild-plugin-swc/src/umd.ts delete mode 100644 packages/libuild/libuild-plugin-swc/src/utils.ts delete mode 100644 packages/libuild/libuild-plugin-swc/tsconfig.json delete mode 100644 packages/libuild/libuild-utils/.eslintrc.cjs delete mode 100644 packages/libuild/libuild-utils/.gitignore delete mode 100644 packages/libuild/libuild-utils/.mocharc.js delete mode 100644 packages/libuild/libuild-utils/CHANGELOG.md delete mode 100644 packages/libuild/libuild-utils/package.json delete mode 100644 packages/libuild/libuild-utils/src/assert.ts delete mode 100644 packages/libuild/libuild-utils/src/deepMerge.ts delete mode 100644 packages/libuild/libuild-utils/src/index.ts delete mode 100644 packages/libuild/libuild-utils/src/resolvePathAndQuery.ts delete mode 100644 packages/libuild/libuild-utils/test/assert.test.ts delete mode 100644 packages/libuild/libuild-utils/test/deepMerge.test.ts delete mode 100644 packages/libuild/libuild-utils/test/resolvePathAndQuery.test.ts delete mode 100644 packages/libuild/libuild-utils/tsconfig.build.json delete mode 100644 packages/libuild/libuild-utils/tsconfig.json delete mode 100644 packages/module/plugin-module-main-fields/.eslintrc.js delete mode 100644 packages/module/plugin-module-main-fields/.npmignore delete mode 100644 packages/module/plugin-module-main-fields/CHANGELOG.md delete mode 100644 packages/module/plugin-module-main-fields/LICENSE delete mode 100644 packages/module/plugin-module-main-fields/README.md delete mode 100644 packages/module/plugin-module-main-fields/jest.config.js delete mode 100644 packages/module/plugin-module-main-fields/modern.config.js delete mode 100644 packages/module/plugin-module-main-fields/package.json delete mode 100644 packages/module/plugin-module-main-fields/src/index.ts delete mode 100644 packages/module/plugin-module-main-fields/tsconfig.json rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/globals.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/child_process.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/cluster.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/dgram.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/dns.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/fs.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/module.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/net.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/readline.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/repl.js (100%) rename packages/{libuild/libuild-plugin-node-polyfill => module/plugin-module-node-polyfill}/src/mock/tls.js (100%) create mode 100644 packages/module/plugin-module-node-polyfill/src/utils.ts delete mode 100644 packages/module/plugin-module-target/.eslintrc.js delete mode 100644 packages/module/plugin-module-target/.npmignore delete mode 100644 packages/module/plugin-module-target/CHANGELOG.md delete mode 100644 packages/module/plugin-module-target/LICENSE delete mode 100644 packages/module/plugin-module-target/README.md delete mode 100644 packages/module/plugin-module-target/jest.config.js delete mode 100644 packages/module/plugin-module-target/modern.config.js delete mode 100644 packages/module/plugin-module-target/package.json delete mode 100644 packages/module/plugin-module-target/src/index.ts delete mode 100644 packages/module/plugin-module-target/tsconfig.json delete mode 100644 packages/solutions/module-tools/jest.config.js create mode 100644 packages/solutions/module-tools/src/builder/esbuild/adapter.ts rename packages/{libuild/libuild-core/src/core/utils.ts => solutions/module-tools/src/builder/esbuild/hook.ts} (84%) create mode 100644 packages/solutions/module-tools/src/builder/esbuild/index.ts create mode 100644 packages/solutions/module-tools/src/builder/esbuild/resolve.ts rename packages/{libuild/libuild-core/src/core => solutions/module-tools/src/builder/esbuild}/sourcemap.ts (92%) create mode 100644 packages/solutions/module-tools/src/builder/esbuild/transform.ts create mode 100644 packages/solutions/module-tools/src/builder/esbuild/watch.ts create mode 100644 packages/solutions/module-tools/src/builder/esbuild/write-file.ts create mode 100644 packages/solutions/module-tools/src/builder/feature/asset.ts create mode 100644 packages/solutions/module-tools/src/builder/feature/format-cjs.ts create mode 100644 packages/solutions/module-tools/src/builder/feature/index.ts create mode 100644 packages/solutions/module-tools/src/builder/feature/json.ts rename packages/{libuild/libuild-core/src/plugins => solutions/module-tools/src/builder/feature}/redirect.ts (52%) create mode 100644 packages/solutions/module-tools/src/builder/feature/style/index.ts rename packages/{libuild/libuild-core/src/plugins => solutions/module-tools/src/builder/feature}/style/lessAliasPlugin.ts (75%) rename packages/{libuild/libuild-core/src/plugins => solutions/module-tools/src/builder/feature}/style/lessRender.ts (75%) rename packages/{libuild/libuild-core/src/plugins => solutions/module-tools/src/builder/feature}/style/postcssTransformer.ts (58%) rename packages/{libuild/libuild-core/src/plugins => solutions/module-tools/src/builder/feature}/style/postcssUrlPlugin.ts (73%) rename packages/{libuild/libuild-core/src/plugins => solutions/module-tools/src/builder/feature}/style/sassRender.ts (78%) rename packages/{libuild/libuild-core/src/plugins => solutions/module-tools/src/builder/feature}/style/transformStyle.ts (63%) rename packages/{libuild/libuild-core/src/plugins => solutions/module-tools/src/builder/feature}/style/utils.ts (89%) create mode 100644 packages/solutions/module-tools/src/builder/feature/swc.ts create mode 100644 packages/solutions/module-tools/src/builder/feature/terser.ts rename packages/{libuild/libuild-core => solutions/module-tools}/src/constants/loader.ts (92%) create mode 100644 packages/solutions/module-tools/src/debug.ts create mode 100644 packages/solutions/module-tools/src/types/esbuild.ts delete mode 100644 packages/solutions/module-tools/src/types/utils.ts create mode 100644 packages/solutions/module-tools/src/utils/assert.ts delete mode 100644 packages/solutions/module-tools/src/utils/context.ts create mode 100644 packages/solutions/module-tools/src/utils/hash.ts create mode 100644 packages/solutions/module-tools/src/utils/index.ts delete mode 100644 packages/solutions/module-tools/src/utils/language.ts delete mode 100644 packages/solutions/module-tools/src/utils/libuild-plugin.ts rename packages/{libuild/libuild-core/src/utils/remapping.ts => solutions/module-tools/src/utils/map.ts} (57%) delete mode 100644 packages/solutions/module-tools/src/utils/path.ts rename packages/solutions/module-tools/src/utils/{tspathsTransform.ts => tspath.ts} (83%) delete mode 100644 packages/solutions/module-tools/tests/fixtures/rollup/error/src/index.ts rename packages/solutions/module-tools/tests/{generatorTsConfig.test.ts => generateDtsInfo.test.ts} (61%) delete mode 100644 packages/solutions/module-tools/tests/rollup.test.ts rename packages/{libuild/libuild-core/test/unit => solutions/module-tools/tests}/style/index.less (100%) rename packages/{libuild/libuild-core/test/unit => solutions/module-tools/tests}/style/less/absolute.less (100%) rename packages/{libuild/libuild-core/test/unit => solutions/module-tools/tests}/style/less/common.less (100%) rename packages/{libuild/libuild-core/test/unit => solutions/module-tools/tests}/style/less/variable.less (100%) create mode 100644 packages/solutions/module-tools/tests/style/rebaseUrl.test.ts create mode 100644 packages/solutions/module-tools/vitest.config.ts delete mode 100644 tests/integration/libuild/.eslintrc.cjs delete mode 100644 tests/integration/libuild/.mocharc.js delete mode 100644 tests/integration/libuild/README.md delete mode 100644 tests/integration/libuild/configs/ignore-dts-files/index.test.ts delete mode 100644 tests/integration/libuild/configs/ignore-dts-files/src/a.ts delete mode 100644 tests/integration/libuild/configs/ignore-dts-files/src/b.d.ts delete mode 100644 tests/integration/libuild/errors/import-inexist-module/custom.test.ts delete mode 100644 tests/integration/libuild/errors/import-inexist-module/error.js delete mode 100644 tests/integration/libuild/errors/import-inexist-module/index.ts delete mode 100644 tests/integration/libuild/fixtures/assets/__snapshots__/asset.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/assets/asset.test.ts delete mode 100644 tests/integration/libuild/fixtures/assets/index.less delete mode 100644 tests/integration/libuild/fixtures/assets/index.ts delete mode 100644 tests/integration/libuild/fixtures/assets/modern.png delete mode 100644 tests/integration/libuild/fixtures/css/entrypoint/a-b.ts delete mode 100644 tests/integration/libuild/fixtures/css/entrypoint/a.ts delete mode 100644 tests/integration/libuild/fixtures/css/entrypoint/css-entry.test.ts delete mode 100644 tests/integration/libuild/fixtures/css/entrypoint/index.css delete mode 100644 tests/integration/libuild/fixtures/css/import/__snapshots__/import.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/css/import/import.test.ts delete mode 100644 tests/integration/libuild/fixtures/css/module/index.module.css delete mode 100644 tests/integration/libuild/fixtures/css/module/index.module.less delete mode 100644 tests/integration/libuild/fixtures/css/module/index.module.sass delete mode 100644 tests/integration/libuild/fixtures/css/module/index.ts delete mode 100644 tests/integration/libuild/fixtures/css/module/module.spec.ts delete mode 100644 tests/integration/libuild/fixtures/data-url/__snapshots__/data-url.spec.ts.snap delete mode 100644 tests/integration/libuild/fixtures/data-url/data-url.spec.ts delete mode 100644 tests/integration/libuild/fixtures/enhanced-resolve-tsconfig-alias/__snapshots__/resolve.spec.ts.snap delete mode 100644 tests/integration/libuild/fixtures/enhanced-resolve-tsconfig-alias/alias/secret.ts delete mode 100644 tests/integration/libuild/fixtures/enhanced-resolve-tsconfig-alias/index.ts delete mode 100644 tests/integration/libuild/fixtures/enhanced-resolve-tsconfig-alias/resolve.spec.ts delete mode 100644 tests/integration/libuild/fixtures/env/dot-env/.env delete mode 100644 tests/integration/libuild/fixtures/env/dot-env/.gitignore delete mode 100644 tests/integration/libuild/fixtures/env/dot-env/__snapshots__/env.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/env/dot-env/env.test.ts delete mode 100644 tests/integration/libuild/fixtures/env/dot-env/index.ts delete mode 100644 tests/integration/libuild/fixtures/external/external.spec.ts delete mode 100644 tests/integration/libuild/fixtures/external/index.tsx delete mode 100644 tests/integration/libuild/fixtures/format/cjs/__snapshots__/format.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/format/cjs/format.test.ts delete mode 100644 tests/integration/libuild/fixtures/format/cjs/index.ts delete mode 100644 tests/integration/libuild/fixtures/format/esm/__snapshots__/format.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/format/esm/format.test.ts delete mode 100644 tests/integration/libuild/fixtures/format/esm/index.ts delete mode 100644 tests/integration/libuild/fixtures/format/iife/__snapshots__/format.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/format/iife/format.test.ts delete mode 100644 tests/integration/libuild/fixtures/format/iife/index.ts delete mode 100644 tests/integration/libuild/fixtures/format/umd/__snapshots__/format.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/format/umd/format.test.ts delete mode 100644 tests/integration/libuild/fixtures/format/umd/index.ts delete mode 100644 tests/integration/libuild/fixtures/globals/__snapshots__/globals.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/globals/globals.test.ts delete mode 100644 tests/integration/libuild/fixtures/globals/index.ts delete mode 100644 tests/integration/libuild/fixtures/input/array/index.ts delete mode 100644 tests/integration/libuild/fixtures/input/array/input.test.ts delete mode 100644 tests/integration/libuild/fixtures/input/empty-object/empty.test.ts delete mode 100644 tests/integration/libuild/fixtures/json/bundleless/index.js delete mode 100644 tests/integration/libuild/fixtures/json/bundleless/json.test.ts delete mode 100644 tests/integration/libuild/fixtures/json/bundleless/zh.json delete mode 100644 tests/integration/libuild/fixtures/json/default-import/index.js delete mode 100644 tests/integration/libuild/fixtures/json/default-import/json.test.ts delete mode 100644 tests/integration/libuild/fixtures/json/default-import/zh.json delete mode 100644 tests/integration/libuild/fixtures/json/named-import/index.js delete mode 100644 tests/integration/libuild/fixtures/json/named-import/json.test.ts delete mode 100644 tests/integration/libuild/fixtures/json/named-import/zh.json delete mode 100644 tests/integration/libuild/fixtures/jsx/__snapshots__/jsx.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/jsx/automatic.tsx delete mode 100644 tests/integration/libuild/fixtures/jsx/default.tsx delete mode 100644 tests/integration/libuild/fixtures/jsx/jsx.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/basic/__snapshots__/basic.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/less/basic/basic.less delete mode 100644 tests/integration/libuild/fixtures/less/basic/basic.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/implementation/__snapshots__/implementation.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/less/implementation/basic.less delete mode 100644 tests/integration/libuild/fixtures/less/implementation/implementation.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/import-css-duplicate/__snapshots__/import-css-duplicate.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/less/import-css-duplicate/import-css-duplicate.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/import-css-duplicate/index.css delete mode 100644 tests/integration/libuild/fixtures/less/import-css-duplicate/index.less delete mode 100644 tests/integration/libuild/fixtures/less/import-css-duplicate/index.ts delete mode 100644 tests/integration/libuild/fixtures/less/import-css/__snapshots__/import-css.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/less/import-css/import-css.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/import-css/style/basic.css delete mode 100644 tests/integration/libuild/fixtures/less/import-css/style/index.less delete mode 100644 tests/integration/libuild/fixtures/less/import/__snapshots__/import.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/less/import/import.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/prependData/__snapshots__/basic.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/less/prependData/basic.less delete mode 100644 tests/integration/libuild/fixtures/less/prependData/basic.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/url-asset/__snapshots__/less-url-asset.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/less/url-asset/index.less delete mode 100644 tests/integration/libuild/fixtures/less/url-asset/index.ts delete mode 100644 tests/integration/libuild/fixtures/less/url-asset/less-url-asset.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/with-function/__snapshots__/func.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/less/with-function/each.less delete mode 100644 tests/integration/libuild/fixtures/less/with-function/func.test.ts delete mode 100644 tests/integration/libuild/fixtures/less/with-function/range.less delete mode 100644 tests/integration/libuild/fixtures/lodash/index.test.ts delete mode 100644 tests/integration/libuild/fixtures/lodash/src/index.ts delete mode 100644 tests/integration/libuild/fixtures/metafile/index.ts delete mode 100644 tests/integration/libuild/fixtures/metafile/metafile.test.ts delete mode 100644 tests/integration/libuild/fixtures/minify/esbuild-target-es6/__snapshots__/minify.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/minify/esbuild-target-es6/index.ts delete mode 100644 tests/integration/libuild/fixtures/minify/esbuild-target-es6/minify.test.ts delete mode 100644 tests/integration/libuild/fixtures/minify/esbuild/__snapshots__/esbuild.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/minify/esbuild/esbuild.test.ts delete mode 100644 tests/integration/libuild/fixtures/minify/esbuild/index.ts delete mode 100644 tests/integration/libuild/fixtures/minify/false/__snapshots__/false.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/minify/false/false.test.ts delete mode 100644 tests/integration/libuild/fixtures/minify/false/index.ts delete mode 100644 tests/integration/libuild/fixtures/minify/terser-target-es6/__snapshots__/terser.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/minify/terser-target-es6/index.ts delete mode 100644 tests/integration/libuild/fixtures/minify/terser-target-es6/terser.test.ts delete mode 100644 tests/integration/libuild/fixtures/minify/terser/__snapshots__/terser.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/minify/terser/index.ts delete mode 100644 tests/integration/libuild/fixtures/minify/terser/terser.test.ts delete mode 100644 tests/integration/libuild/fixtures/modules/mixin/answer.ts delete mode 100644 tests/integration/libuild/fixtures/modules/mixin/index.ts delete mode 100644 tests/integration/libuild/fixtures/name/a.css delete mode 100644 tests/integration/libuild/fixtures/name/index.ts delete mode 100644 tests/integration/libuild/fixtures/name/other.ts delete mode 100644 tests/integration/libuild/fixtures/name/output.spec.ts delete mode 100644 tests/integration/libuild/fixtures/name/share.ts delete mode 100644 tests/integration/libuild/fixtures/no-bundle/no-bundle.test.ts delete mode 100644 tests/integration/libuild/fixtures/no-bundle/src/index.less delete mode 100644 tests/integration/libuild/fixtures/no-bundle/src/index.module.less delete mode 100644 tests/integration/libuild/fixtures/no-bundle/src/index.ts delete mode 100644 tests/integration/libuild/fixtures/no-bundle/src/logo.png delete mode 100644 tests/integration/libuild/fixtures/node-enhanced/buildin.ts delete mode 100644 tests/integration/libuild/fixtures/node-enhanced/external.d.ts delete mode 100644 tests/integration/libuild/fixtures/node-enhanced/external.ts delete mode 100644 tests/integration/libuild/fixtures/node-enhanced/inner.ts delete mode 100644 tests/integration/libuild/fixtures/node-enhanced/node-enhanced.spec.ts delete mode 100644 tests/integration/libuild/fixtures/node-enhanced/normal.ts delete mode 100644 tests/integration/libuild/fixtures/platform/browser-test/http.js delete mode 100644 tests/integration/libuild/fixtures/platform/browser-test/index.d.ts delete mode 100644 tests/integration/libuild/fixtures/platform/browser-test/index.js delete mode 100644 tests/integration/libuild/fixtures/platform/browser-test/package.json delete mode 100644 tests/integration/libuild/fixtures/platform/browser-test/xhr.js delete mode 100644 tests/integration/libuild/fixtures/platform/browser.ts delete mode 100644 tests/integration/libuild/fixtures/platform/node.ts delete mode 100644 tests/integration/libuild/fixtures/platform/platform.spec.ts delete mode 100644 tests/integration/libuild/fixtures/postcss/autoModules/auto-modules.test.ts delete mode 100644 tests/integration/libuild/fixtures/postcss/autoModules/index.css delete mode 100644 tests/integration/libuild/fixtures/postcss/config-file/__snapshots__/config-file.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/postcss/config-file/config-file.test.ts delete mode 100644 tests/integration/libuild/fixtures/postcss/config-file/index.css delete mode 100644 tests/integration/libuild/fixtures/postcss/config-file/postcss.config.js delete mode 100644 tests/integration/libuild/fixtures/redirect/disable-redirect.test.ts delete mode 100644 tests/integration/libuild/fixtures/redirect/redirect.test.ts delete mode 100644 tests/integration/libuild/fixtures/redirect/src/style.ts delete mode 100644 tests/integration/libuild/fixtures/resolve-node-protocol/__snapshots__/protocol.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/resolve-node-protocol/protocol.test.ts delete mode 100644 tests/integration/libuild/fixtures/resolve-with-condition-exports/.gitignore delete mode 100644 tests/integration/libuild/fixtures/resolve-with-condition-exports/__snapshots__/resolve-with-condition-exports.spec.ts.snap delete mode 100644 tests/integration/libuild/fixtures/resolve-with-condition-exports/resolve-with-condition-exports.spec.ts delete mode 100644 tests/integration/libuild/fixtures/resolve-with-mainFields/.gitignore delete mode 100644 tests/integration/libuild/fixtures/resolve-with-mainFields/__snapshots__/resolve-with-mainFields.spec.ts.snap delete mode 100644 tests/integration/libuild/fixtures/resolve-with-mainFields/resolve-with-mainFields.spec.ts delete mode 100644 tests/integration/libuild/fixtures/resolve/__snapshots__/resolve.spec.ts.snap delete mode 100644 tests/integration/libuild/fixtures/resolve/alias/secret.ts delete mode 100644 tests/integration/libuild/fixtures/resolve/false.ts delete mode 100644 tests/integration/libuild/fixtures/resolve/index.ts delete mode 100644 tests/integration/libuild/fixtures/resolve/other.ts delete mode 100644 tests/integration/libuild/fixtures/resolve/resolve.spec.ts delete mode 100644 tests/integration/libuild/fixtures/resolve/tsconfig.json delete mode 100644 tests/integration/libuild/fixtures/sass/basic/__snapshots__/basic.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/sass/basic/basic.scss delete mode 100644 tests/integration/libuild/fixtures/sass/basic/basic.test.ts delete mode 100644 tests/integration/libuild/fixtures/sass/implementation/__snapshots__/implementation.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/sass/implementation/basic.scss delete mode 100644 tests/integration/libuild/fixtures/sass/implementation/implementation.test.ts delete mode 100644 tests/integration/libuild/fixtures/sass/import/__snapshots__/import.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/sass/import/import.scss delete mode 100644 tests/integration/libuild/fixtures/sass/import/import.test.ts delete mode 100644 tests/integration/libuild/fixtures/sass/prependData/__snapshots__/basic.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/sass/prependData/basic.scss delete mode 100644 tests/integration/libuild/fixtures/sass/prependData/basic.test.ts delete mode 100644 tests/integration/libuild/fixtures/sass/url/__snapshots__/sass-url.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/sass/url/index.scss delete mode 100644 tests/integration/libuild/fixtures/sass/url/sass-url.test.ts delete mode 100644 tests/integration/libuild/fixtures/sideEffects/antd-mobile/src/global.js delete mode 100644 tests/integration/libuild/fixtures/sideEffects/antd-mobile/src/index.js delete mode 100644 tests/integration/libuild/fixtures/sideEffects/config.ts delete mode 100644 tests/integration/libuild/fixtures/sideEffects/index.ts delete mode 100644 tests/integration/libuild/fixtures/sideEffects/other.ts delete mode 100644 tests/integration/libuild/fixtures/sideEffects/sideeffect.test.ts delete mode 100644 tests/integration/libuild/fixtures/sourcemap/external/external.test.ts delete mode 100644 tests/integration/libuild/fixtures/sourcemap/external/index.ts delete mode 100644 tests/integration/libuild/fixtures/sourcemap/false/false.test.ts delete mode 100644 tests/integration/libuild/fixtures/sourcemap/false/index.ts delete mode 100644 tests/integration/libuild/fixtures/sourcemap/inline/index.ts delete mode 100644 tests/integration/libuild/fixtures/sourcemap/inline/inline.test.ts delete mode 100644 tests/integration/libuild/fixtures/sourcemap/true/index.ts delete mode 100644 tests/integration/libuild/fixtures/sourcemap/true/true.test.ts delete mode 100644 tests/integration/libuild/fixtures/splitting/cjs/__snapshots__/splitting.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/splitting/cjs/dynamic.ts delete mode 100644 tests/integration/libuild/fixtures/splitting/cjs/index.ts delete mode 100644 tests/integration/libuild/fixtures/splitting/cjs/lib/dynamic-2A63DP2P.js delete mode 100644 tests/integration/libuild/fixtures/splitting/cjs/lib/index.js delete mode 100644 tests/integration/libuild/fixtures/splitting/cjs/splitting.test.ts delete mode 100644 tests/integration/libuild/fixtures/splitting/esm/__snapshots__/splitting.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/splitting/esm/dynamic.ts delete mode 100644 tests/integration/libuild/fixtures/splitting/esm/index.ts delete mode 100644 tests/integration/libuild/fixtures/splitting/esm/splitting.test.ts delete mode 100644 tests/integration/libuild/fixtures/stage/index.ts delete mode 100644 tests/integration/libuild/fixtures/stage/stage.spec.ts delete mode 100644 tests/integration/libuild/fixtures/style-inject/index.css delete mode 100644 tests/integration/libuild/fixtures/style-inject/inject.tsx delete mode 100644 tests/integration/libuild/fixtures/style-inject/style-inject.test.ts delete mode 100644 tests/integration/libuild/fixtures/target/__snapshots__/target.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/target/index.ts delete mode 100644 tests/integration/libuild/fixtures/target/target.test.ts delete mode 100644 tests/integration/libuild/fixtures/treeshaking/__snapshots__/treeshaking.test.ts.snap delete mode 100644 tests/integration/libuild/fixtures/treeshaking/index.ts delete mode 100644 tests/integration/libuild/fixtures/treeshaking/mylib/src/exports.ts delete mode 100644 tests/integration/libuild/fixtures/treeshaking/mylib/src/index.ts delete mode 100644 tests/integration/libuild/fixtures/treeshaking/mylib/src/lib.ts delete mode 100644 tests/integration/libuild/fixtures/treeshaking/treeshaking.test.ts delete mode 100644 tests/integration/libuild/fixtures/types.d.ts delete mode 100644 tests/integration/libuild/fixtures/virtual-module/index.ts delete mode 100644 tests/integration/libuild/fixtures/virtual-module/raw.ts delete mode 100644 tests/integration/libuild/fixtures/virtual-module/virtual.spec.ts delete mode 100644 tests/integration/libuild/fixtures/watch/basic/basic.test.ts delete mode 100644 tests/integration/libuild/fixtures/watch/basic/index.ts delete mode 100644 tests/integration/libuild/fixtures/watch/changed/changed.test.ts delete mode 100644 tests/integration/libuild/fixtures/watch/changed/index.ts delete mode 100644 tests/integration/libuild/fixtures/watch/error/error.test.ts delete mode 100644 tests/integration/libuild/fixtures/watch/error/index.ts delete mode 100644 tests/integration/libuild/fixtures/watch/first-bundle/error.test.ts delete mode 100644 tests/integration/libuild/fixtures/watch/first-bundle/index.ts delete mode 100644 tests/integration/libuild/package.json delete mode 100644 tests/integration/libuild/plugins/babel/__snapshots__/babel.test.ts.snap delete mode 100644 tests/integration/libuild/plugins/babel/babel.test.ts delete mode 100644 tests/integration/libuild/plugins/babel/index.ts delete mode 100644 tests/integration/libuild/plugins/node-polyfill/index.ts delete mode 100644 tests/integration/libuild/plugins/node-polyfill/polyfill.test.ts delete mode 100644 tests/integration/libuild/plugins/svgr/__snapshots__/svgr.test.ts.snap delete mode 100644 tests/integration/libuild/plugins/svgr/src/index.ts delete mode 100644 tests/integration/libuild/plugins/svgr/svgr.test.ts delete mode 100644 tests/integration/libuild/plugins/svgr/types.d.ts delete mode 100644 tests/integration/libuild/plugins/swc/__snapshots__/swc.test.ts.snap delete mode 100644 tests/integration/libuild/plugins/swc/index.tsx delete mode 100644 tests/integration/libuild/plugins/swc/swc.test.ts delete mode 100644 tests/integration/libuild/toolkit/expect.ts delete mode 100644 tests/integration/libuild/toolkit/index.ts delete mode 100644 tests/integration/libuild/toolkit/libuilderTest.ts delete mode 100644 tests/integration/libuild/toolkit/waitForEqual.ts delete mode 100644 tests/integration/libuild/tsconfig.json create mode 100644 tests/integration/module/fixtures/build/alias/alias.test.ts rename tests/integration/module/{src/fixtures/alias/ts/bundle-function.config.ts => fixtures/build/alias/js/function.config.ts} (86%) rename tests/integration/module/{src/fixtures/alias/ts/bundle-object.config.ts => fixtures/build/alias/js/object.config.ts} (86%) rename tests/integration/module/{src/fixtures => fixtures/build}/alias/js/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/alias/js/src/b.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/alias/js/src/index.js (100%) rename tests/integration/module/{src/fixtures/alias/js/bundle-function.config.ts => fixtures/build/alias/ts/function.config.ts} (86%) rename tests/integration/module/{src/fixtures/target/config.ts => fixtures/build/alias/ts/modern.config.ts} (69%) rename tests/integration/module/{src/fixtures/alias/js/bundle-object.config.ts => fixtures/build/alias/ts/object.config.ts} (86%) rename tests/integration/module/{src/fixtures => fixtures/build}/alias/ts/package.json (100%) rename {packages/solutions/module-tools/tests/fixtures/rollup/base => tests/integration/module/fixtures/build/alias/ts}/src/b.ts (100%) rename {packages/solutions/module-tools/tests/fixtures/rollup/base => tests/integration/module/fixtures/build/alias/ts}/src/index.ts (100%) rename {packages/solutions/module-tools/tests/fixtures/rollup/base => tests/integration/module/fixtures/build/alias/ts}/tsconfig.json (100%) create mode 100644 tests/integration/module/fixtures/build/asset/asset.test.ts create mode 100644 tests/integration/module/fixtures/build/asset/limit/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/asset/limit/package.json rename tests/integration/module/{src/fixtures/svgr => fixtures/build/asset/limit}/src/index.js (100%) rename tests/integration/{libuild/fixtures/assets => module/fixtures/build/asset/limit/src}/logo.svg (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/asset/path/package.json (100%) rename tests/integration/module/{src/fixtures/asset => fixtures/build/asset/path}/path.bundle.config.ts (100%) rename tests/integration/module/{src/fixtures/asset => fixtures/build/asset/path}/path.bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/asset/path/src/a.png (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/asset/path/src/index.jsx (100%) create mode 100644 tests/integration/module/fixtures/build/asset/publicPath/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/asset/publicPath/package.json create mode 100644 tests/integration/module/fixtures/build/asset/publicPath/src/index.js rename tests/integration/{libuild/fixtures/redirect => module/fixtures/build/asset/publicPath}/src/logo.svg (100%) rename tests/integration/module/{src/fixtures/svgr/default.config.ts => fixtures/build/asset/svgr/bundle.config.ts} (89%) rename tests/integration/module/{src/fixtures => fixtures/build/asset}/svgr/bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build/asset}/svgr/exclude.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build/asset}/svgr/package.json (100%) create mode 100644 tests/integration/module/fixtures/build/asset/svgr/src/index.js rename tests/integration/{libuild/fixtures/sass/url/common => module/fixtures/build/asset/svgr/src}/logo.svg (100%) rename tests/integration/module/{src => fixtures/build/autoExternal}/autoExternal.test.ts (94%) rename tests/integration/module/{src/fixtures => fixtures/build}/autoExternal/config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/autoExternal/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/autoExternal/src/env.d.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/autoExternal/src/index.ts (100%) create mode 100644 tests/integration/module/fixtures/build/banner-footer/banner.test.ts create mode 100644 tests/integration/module/fixtures/build/banner-footer/bundle.config.ts create mode 100644 tests/integration/module/fixtures/build/banner-footer/bundleless.config.ts create mode 100644 tests/integration/module/fixtures/build/banner-footer/package.json create mode 100644 tests/integration/module/fixtures/build/banner-footer/src/index.css create mode 100644 tests/integration/module/fixtures/build/banner-footer/src/index.ts rename tests/integration/module/{src/fixtures/globalVars/ts => fixtures/build/banner-footer}/tsconfig.json (100%) rename tests/integration/module/{src => fixtures/build/buildType}/buildType.test.ts (82%) rename tests/integration/module/{src/fixtures => fixtures/build}/buildType/bundle.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/buildType/bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/buildType/package.json (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/build/buildType}/src/index.js (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/build/buildType}/src/utils.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/config-1.ts (100%) rename tests/integration/module/{src => fixtures/build/copy}/copy.test.ts (94%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/src/index.html (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/src/test.txt (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/temp-1/a.png (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/temp-2/a.png (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/temp-3/a.png (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/temp-3/b.txt (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/copy/temp-4/index.html (100%) rename tests/integration/module/{src => fixtures/build/decorator}/__snapshots__/decorator.test.ts.snap (96%) rename tests/integration/module/{src => fixtures/build/decorator}/decorator.test.ts (76%) rename tests/integration/module/{src/fixtures => fixtures/build}/decorator/modern.config.ts (76%) rename tests/integration/module/{src/fixtures => fixtures/build}/decorator/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/decorator/src/index.ts (100%) rename tests/integration/module/{src/globalVars.test.ts => fixtures/build/define/define.test.ts} (77%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/js/bundle.config.ts (100%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/js/bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/js/package.json (100%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/js/src/index.js (100%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/ts/bundle.config.ts (100%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/ts/bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/ts/package.json (100%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/ts/src/env.d.ts (100%) rename tests/integration/module/{src/fixtures/globalVars => fixtures/build/define}/ts/src/index.ts (100%) rename tests/integration/module/{src/fixtures/inputFilter => fixtures/build/define/ts}/tsconfig.json (57%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/abortOnError-bundle.ts (87%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/abortOnError-bundleless.ts (87%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/distPath-bundle.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/distPath-bundleless.ts (100%) rename tests/integration/module/{src => fixtures/build/dts}/dts.test.ts (93%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/false-bundle.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/false-bundleless.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/only-bundle.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/only-bundleless.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/src-error/index.ts (100%) rename {packages/solutions/module-tools/tests/fixtures/rollup/error => tests/integration/module/fixtures/build/dts}/src/b.ts (100%) rename tests/integration/module/{src/fixtures/alias/ts => fixtures/build/dts}/src/index.ts (100%) rename tests/integration/module/{src/fixtures/alias/ts/src => fixtures/build/dts/src1}/b.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/src1/index.ts (100%) rename tests/integration/module/{src/fixtures/dts/src => fixtures/build/dts/src2}/b.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/src2/index.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/tsconfig-bundle.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/tsconfig-bundleless.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/tsconfig-error.json (100%) rename {packages/solutions/module-tools/tests/fixtures/rollup/error => tests/integration/module/fixtures/build/dts}/tsconfig.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/tsconfigPath-bundle.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/dts/tsconfigPath-bundleless.ts (80%) rename tests/integration/module/{src => fixtures/build/esbuildOptions}/esbuildOptions.test.ts (76%) rename tests/integration/module/{src/fixtures => fixtures/build}/esbuildOptions/modern.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/esbuildOptions/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/esbuildOptions/src/index.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/externals/config.ts (100%) rename tests/integration/module/{src => fixtures/build/externals}/externals.test.ts (88%) rename tests/integration/module/{src/fixtures => fixtures/build}/externals/package.json (100%) rename tests/integration/module/{src/fixtures/entry => fixtures/build/externals}/src/common.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/externals/src/index.ts (100%) rename tests/integration/module/{src => fixtures/build/format}/__snapshots__/format.test.ts.snap (73%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/cjs-bundle.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/cjs-bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/cjs/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/cjs/src/index.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/cjs/src/utils.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/esm-bundle.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/esm-bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/esm/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/esm/src/index.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/esm/src/utils.js (100%) rename tests/integration/module/{src => fixtures/build/format}/format.test.ts (87%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/iife-bundle.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/iife-bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/iife/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/iife/src/index.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/iife/src/utils.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/umd-bundle.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/umd-bundleless.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/umd/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/umd/src/index.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/format/umd/src/utils.js (100%) rename tests/integration/module/{src/fixtures/entry => fixtures/build/input}/array.ts (100%) rename tests/integration/module/{src/entry.test.ts => fixtures/build/input/input.test.ts} (50%) rename tests/integration/module/{src/fixtures/inputFilter => fixtures/build/input}/modern.config.ts (100%) rename tests/integration/module/{src/fixtures/entry => fixtures/build/input}/object.ts (100%) rename tests/integration/module/{src/fixtures/entry => fixtures/build/input}/package.json (100%) rename tests/integration/module/{src/fixtures/entry => fixtures/build/input}/src/browser.ts (100%) rename tests/integration/module/{src/fixtures/externals => fixtures/build/input}/src/common.ts (100%) rename tests/integration/module/{src/fixtures/inputFilter => fixtures/build/input}/src/index.a.ts (100%) rename tests/integration/module/{src/fixtures/entry => fixtures/build/input}/src/index.ts (100%) rename tests/integration/module/{src/fixtures/alias/ts => fixtures/build/input}/tsconfig.json (100%) rename tests/integration/module/{src/fixtures/jsx/automatic-bundle.config.ts => fixtures/build/jsx/automatic.config.ts} (83%) create mode 100644 tests/integration/module/fixtures/build/jsx/jsx.test.ts rename tests/integration/module/{src/fixtures => fixtures/build}/jsx/package.json (100%) create mode 100644 tests/integration/module/fixtures/build/jsx/preserve.config.ts rename tests/integration/module/{src/fixtures => fixtures/build}/jsx/src/index.jsx (100%) rename tests/integration/module/{src/fixtures/jsx/transform-bundle.config.ts => fixtures/build/jsx/transform.config.ts} (81%) rename tests/integration/module/{src/fixtures => fixtures/build}/metafile/config.ts (100%) rename tests/integration/module/{src => fixtures/build/metafile}/metafile.test.ts (81%) rename tests/integration/module/{src/fixtures => fixtures/build}/metafile/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/metafile/src/common.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/metafile/src/index.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/minify/config.ts (100%) rename tests/integration/module/{src => fixtures/build/minify}/minify.test.ts (92%) rename tests/integration/module/{src/fixtures => fixtures/build}/minify/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/minify/src/common.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/minify/src/index.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/platform/browser.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/platform/node.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/platform/package.json (100%) rename tests/integration/module/{src => fixtures/build/platform}/platform.test.ts (84%) rename tests/integration/module/{src/fixtures => fixtures/build}/platform/src/common.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/platform/src/index.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/redirect/no-redirect.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/redirect/package.json (100%) create mode 100644 tests/integration/module/fixtures/build/redirect/redirect.test.ts rename tests/integration/module/{src/fixtures => fixtures/build}/redirect/redirect.ts (93%) create mode 100644 tests/integration/module/fixtures/build/redirect/src/alias.ts rename tests/integration/{libuild/fixtures/redirect/src/style.module.less => module/fixtures/build/redirect/src/index.module.css} (96%) create mode 100644 tests/integration/module/fixtures/build/redirect/src/index.ts rename tests/integration/{libuild/plugins/svgr/src/svg => module/fixtures/build/redirect/src}/logo.svg (100%) rename tests/integration/{libuild/fixtures/enhanced-resolve-tsconfig-alias => module/fixtures/build/redirect}/tsconfig.json (60%) create mode 100644 tests/integration/module/fixtures/build/resolve/data-url/dataurl.test.ts rename tests/integration/{libuild/fixtures => module/fixtures/build/resolve}/data-url/index.ts (98%) rename tests/integration/module/{src/fixtures/buildPlatform/config.ts => fixtures/build/resolve/data-url/modern.config.ts} (100%) create mode 100644 tests/integration/module/fixtures/build/resolve/data-url/package.json rename tests/integration/{libuild/fixtures/resolve-node-protocol => module/fixtures/build/resolve/node-protocol}/index.ts (100%) create mode 100644 tests/integration/module/fixtures/build/resolve/node-protocol/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/resolve/node-protocol/package.json create mode 100644 tests/integration/module/fixtures/build/resolve/node-protocol/protocol.test.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-condition-exports/.gitignore rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/entry1.ts (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/entry2.ts (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports/entry4.ts => module/fixtures/build/resolve/with-condition-exports/entry3.ts} (50%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports/entry3.ts => module/fixtures/build/resolve/with-condition-exports/entry4.ts} (100%) create mode 100644 tests/integration/module/fixtures/build/resolve/with-condition-exports/modern-node.config.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-condition-exports/modern.config.ts rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib1/package.json (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib1/src/index.cjs (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib1/src/index.mjs (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib2/package.json (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib2/src/index.cjs (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib2/src/index.mjs (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib2/src/module.js (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib3/package.json (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib3/src/browser.js (100%) rename tests/integration/{libuild/fixtures/resolve-with-condition-exports => module/fixtures/build/resolve/with-condition-exports}/node_modules/lib3/src/node.js (100%) create mode 100644 tests/integration/module/fixtures/build/resolve/with-condition-exports/package.json create mode 100644 tests/integration/module/fixtures/build/resolve/with-condition-exports/resolve-with-condition-exports.test.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-js-extensions/example.mts create mode 100644 tests/integration/module/fixtures/build/resolve/with-js-extensions/index.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-js-extensions/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-js-extensions/package.json create mode 100644 tests/integration/module/fixtures/build/resolve/with-js-extensions/resolve-with-js-extensions.test.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-mainFields/.gitignore rename tests/integration/{libuild/fixtures/resolve-with-mainFields/index.ts => module/fixtures/build/resolve/with-mainFields/entry1.ts} (100%) create mode 100644 tests/integration/module/fixtures/build/resolve/with-mainFields/entry2.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-mainFields/modern.config.ts rename tests/integration/{libuild/fixtures/resolve-with-mainFields => module/fixtures/build/resolve/with-mainFields}/node_modules/lib1/package.json (100%) rename tests/integration/{libuild/fixtures/resolve-with-mainFields => module/fixtures/build/resolve/with-mainFields}/node_modules/lib1/src/index.ts (100%) rename tests/integration/{libuild/fixtures/sideEffects/antd-mobile => module/fixtures/build/resolve/with-mainFields/node_modules/lib2}/package.json (50%) create mode 100644 tests/integration/module/fixtures/build/resolve/with-mainFields/node_modules/lib2/src/browser.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-mainFields/node_modules/lib2/src/main.ts create mode 100644 tests/integration/module/fixtures/build/resolve/with-mainFields/package.json create mode 100644 tests/integration/module/fixtures/build/resolve/with-mainFields/resolve-with-mainFields.test.ts rename tests/integration/module/{src/fixtures => fixtures/build}/sideEffects/index.css (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/sideEffects/index.ts (100%) rename tests/integration/module/{src/fixtures/sideEffects/config.ts => fixtures/build/sideEffects/modern.config.ts} (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/sideEffects/package.json (100%) rename tests/integration/module/{src => fixtures/build/sideEffects}/sideEffects.test.ts (62%) rename tests/integration/module/{src/fixtures => fixtures/build}/sourceDir/config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/sourceDir/lib/browser.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/sourceDir/lib/common.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/sourceDir/lib/index.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/sourceDir/package.json (100%) rename tests/integration/module/{src => fixtures/build/sourceDir}/sourceDir.test.ts (86%) rename tests/integration/module/{src/__snapshots__/sourcemap.test.ts.snap => fixtures/build/sourceMap/__snapshots__/sourceMap.test.ts.snap} (83%) rename tests/integration/module/{src/fixtures/sourcemap => fixtures/build/sourceMap}/external.ts (100%) rename tests/integration/module/{src/fixtures/sourcemap => fixtures/build/sourceMap}/false.ts (100%) rename tests/integration/module/{src/fixtures/sourcemap => fixtures/build/sourceMap}/inline.ts (100%) rename tests/integration/module/{src/fixtures/sourcemap => fixtures/build/sourceMap}/package.json (100%) rename tests/integration/module/{src/sourcemap.test.ts => fixtures/build/sourceMap/sourceMap.test.ts} (94%) rename tests/integration/module/{src/fixtures/buildPreset/error => fixtures/build/sourceMap}/src/index.js (100%) rename tests/integration/module/{src/fixtures/buildPreset/error => fixtures/build/sourceMap}/src/utils.js (100%) rename tests/integration/module/{src/fixtures/sourcemap => fixtures/build/sourceMap}/true.ts (100%) create mode 100644 tests/integration/module/fixtures/build/splitting/cjs.config.ts rename tests/integration/module/{src/fixtures => fixtures/build}/splitting/config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/splitting/package.json (100%) rename tests/integration/module/{src => fixtures/build/splitting}/splitting.test.ts (63%) rename tests/integration/module/{src/fixtures => fixtures/build}/splitting/src/common.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/splitting/src/index.ts (100%) rename tests/integration/{libuild/fixtures/css/import => module/fixtures/build/style/css}/import.css (57%) create mode 100644 tests/integration/module/fixtures/build/style/css/import.test.ts rename tests/integration/{libuild/fixtures/css/import => module/fixtures/build/style/css}/lib1.css (100%) rename tests/integration/{libuild/fixtures/css/import => module/fixtures/build/style/css}/lib2.css (100%) rename tests/integration/module/{src/fixtures/watch/bundleless.config.ts => fixtures/build/style/css/modern.config.ts} (67%) rename tests/integration/module/{src/fixtures/tools => fixtures/build/style/css}/package.json (51%) create mode 100644 tests/integration/module/fixtures/build/style/less/.gitignore rename tests/integration/{libuild/fixtures/less/url-asset => module/fixtures/build/style/less}/assets/normal.ttf (100%) create mode 100644 tests/integration/module/fixtures/build/style/less/import.config.ts rename tests/integration/{libuild/fixtures => module/fixtures/build/style}/less/import/extension/index.less (100%) rename tests/integration/{libuild/fixtures => module/fixtures/build/style}/less/import/extension/util.less (100%) rename tests/integration/{libuild/fixtures => module/fixtures/build/style}/less/import/foundation/code.less (100%) rename tests/integration/{libuild/fixtures => module/fixtures/build/style}/less/import/index.less (68%) rename tests/integration/{libuild/fixtures => module/fixtures/build/style}/less/import/index.ts (58%) rename tests/integration/{libuild/fixtures => module/fixtures/build/style}/less/import/prefer/index.js (100%) rename tests/integration/{libuild/fixtures => module/fixtures/build/style}/less/import/prefer/index.less (100%) create mode 100644 tests/integration/module/fixtures/build/style/less/index.less create mode 100644 tests/integration/module/fixtures/build/style/less/less.test.ts create mode 100644 tests/integration/module/fixtures/build/style/less/modern.config.ts rename tests/integration/{libuild/fixtures/less/import-css/style/alias => module/fixtures/build/style/less/nest}/alias.css (100%) rename tests/integration/{libuild/fixtures/less/url-asset => module/fixtures/build/style/less}/nest/nest.less (100%) create mode 100644 tests/integration/module/fixtures/build/style/less/node_modules/lib1/index.css rename tests/integration/{libuild/fixtures/treeshaking/mylib => module/fixtures/build/style/less/node_modules/lib1}/package.json (55%) create mode 100644 tests/integration/module/fixtures/build/style/less/package.json create mode 100644 tests/integration/module/fixtures/build/style/others/index.js create mode 100644 tests/integration/module/fixtures/build/style/others/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/style/others/package.json create mode 100644 tests/integration/module/fixtures/build/style/others/style.css create mode 100644 tests/integration/module/fixtures/build/style/others/style.test.ts create mode 100644 tests/integration/module/fixtures/build/style/postcss/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/style/postcss/package.json create mode 100644 tests/integration/module/fixtures/build/style/postcss/postcss.test.ts rename tests/integration/module/{src/fixtures/tools/src => fixtures/build/style/postcss}/style.css (100%) create mode 100644 tests/integration/module/fixtures/build/style/sass/.gitignore rename tests/integration/{libuild/fixtures/sass/import => module/fixtures/build/style/sass}/foundation/_code.scss (100%) rename tests/integration/{libuild/fixtures/sass/import => module/fixtures/build/style/sass}/foundation/_lists.scss (100%) rename tests/integration/{libuild/fixtures/sass/url/common => module/fixtures/build/style/sass/foundation}/index.scss (100%) rename tests/integration/module/{src/fixtures/svgr/src => fixtures/build/style/sass/foundation}/logo.svg (100%) create mode 100644 tests/integration/module/fixtures/build/style/sass/index.scss create mode 100644 tests/integration/module/fixtures/build/style/sass/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/style/sass/node_modules/lib1/index.css create mode 100644 tests/integration/module/fixtures/build/style/sass/node_modules/lib1/package.json create mode 100644 tests/integration/module/fixtures/build/style/sass/package.json create mode 100644 tests/integration/module/fixtures/build/style/sass/scss.test.ts rename tests/integration/module/{src/fixtures/designSystem/bundleless.config.ts => fixtures/build/style/tailwindcss/design-system.config.ts} (63%) create mode 100644 tests/integration/module/fixtures/build/style/tailwindcss/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/style/tailwindcss/package.json rename tests/integration/module/{src/fixtures/designSystem/src/index.css => fixtures/build/style/tailwindcss/style.css} (100%) create mode 100644 tests/integration/module/fixtures/build/style/tailwindcss/tailwindcss.test.ts rename tests/integration/module/{src/fixtures/watch/config.ts => fixtures/build/target/es5.config.ts} (74%) rename tests/integration/module/{src/fixtures => fixtures/build}/target/package.json (100%) create mode 100644 tests/integration/module/fixtures/build/target/src/index.js create mode 100644 tests/integration/module/fixtures/build/target/target.test.ts create mode 100644 tests/integration/module/fixtures/build/transformImport/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/transformImport/package.json create mode 100644 tests/integration/module/fixtures/build/transformImport/src/index.ts create mode 100644 tests/integration/module/fixtures/build/transformImport/transformImport.test.ts rename tests/integration/module/{src/fixtures => fixtures/build}/transformLodash/modern.config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/transformLodash/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/transformLodash/src/a.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/transformLodash/src/b.js (100%) rename tests/integration/module/{src => fixtures/build/transformLodash}/transformLodash.test.ts (92%) create mode 100644 tests/integration/module/fixtures/build/tsconfig/modern.config.ts create mode 100644 tests/integration/module/fixtures/build/tsconfig/package.json rename tests/integration/module/{src/fixtures/dts/src1 => fixtures/build/tsconfig/src}/b.ts (100%) rename tests/integration/module/{src/fixtures/dts => fixtures/build/tsconfig}/src/index.ts (63%) rename tests/integration/module/{src/fixtures/dts/tsconfig.json => fixtures/build/tsconfig/tsconfig-test.json} (82%) create mode 100644 tests/integration/module/fixtures/build/tsconfig/tsconfig.test.ts rename tests/integration/module/{src => fixtures/build/umdGlobals}/__snapshots__/umdGlobals.test.ts.snap (69%) rename tests/integration/module/{src/fixtures => fixtures/build}/umdGlobals/config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/umdGlobals/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/umdGlobals/src/common.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/umdGlobals/src/index.js (100%) rename tests/integration/module/{src => fixtures/build/umdGlobals}/umdGlobals.test.ts (92%) rename tests/integration/module/{src/fixtures => fixtures/build}/umdModuleName/config.ts (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/umdModuleName/package.json (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/umdModuleName/src/common.js (100%) rename tests/integration/module/{src/fixtures => fixtures/build}/umdModuleName/src/index.js (100%) rename tests/integration/module/{src => fixtures/build/umdModuleName}/umdModuleName.test.ts (84%) create mode 100644 tests/integration/module/fixtures/constants.ts rename tests/integration/module/{src => }/fixtures/dev/before-dev-menu.ts (100%) rename tests/integration/module/{src => }/fixtures/dev/config-with-plugin.ts (100%) rename tests/integration/module/{src => }/fixtures/dev/config-with-plugins.ts (100%) rename tests/integration/module/{src => }/fixtures/dev/config.ts (100%) rename tests/integration/module/{src => fixtures/dev}/dev.test.ts (95%) rename tests/integration/module/{src => }/fixtures/dev/package.json (100%) rename tests/integration/module/{src => }/fixtures/dev/plugin-1.ts (100%) rename tests/integration/module/{src => }/fixtures/dev/plugin-2.ts (100%) rename tests/integration/module/{src => }/fixtures/dev/plugin-3.ts (100%) rename tests/integration/module/{src/fixtures/buildPreset/function => fixtures/dev}/src/index.js (100%) rename tests/integration/module/{src/fixtures/buildPreset/string => fixtures/dev}/src/utils.js (100%) rename tests/integration/module/{src => fixtures/platform}/buildPlatform.test.ts (96%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/config-with-plugin.ts (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/config-with-plugin2.ts (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/config-with-plugins-1.ts (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/config-with-plugins.ts (100%) create mode 100644 tests/integration/module/fixtures/platform/config.ts rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/package.json (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/plugin-1.ts (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/plugin-2.ts (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/plugin-3.ts (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/plugin-4.ts (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/plugin-5.ts (100%) rename tests/integration/module/{src/fixtures/buildPlatform => fixtures/platform}/plugin-6.ts (100%) rename tests/integration/module/{src/fixtures/buildPreset/string => fixtures/platform}/src/index.js (100%) rename tests/integration/module/{src/fixtures/buildType => fixtures/platform}/src/utils.js (100%) rename tests/integration/module/{src => fixtures/preset}/buildPreset.test.ts (96%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/error-1.config.ts (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/error-2.config.ts (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/error-3.config.ts (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/error/package.json (100%) rename tests/integration/module/{src/fixtures/buildType => fixtures/preset/error}/src/index.js (100%) rename tests/integration/module/{src/fixtures/dev => fixtures/preset/error}/src/utils.js (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/extend-preset.config.ts (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/function.config.ts (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/function/package.json (100%) rename tests/integration/module/{src/fixtures/dev => fixtures/preset/function}/src/index.js (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/function/src/utils.js (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/package.json (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/string.config.ts (100%) rename tests/integration/module/{src/fixtures/buildPreset => fixtures/preset}/string/package.json (100%) rename tests/integration/module/{src/fixtures/sourcemap => fixtures/preset/string}/src/index.js (100%) rename tests/integration/module/{src/fixtures/sourcemap => fixtures/preset/string}/src/utils.js (100%) rename tests/integration/module/{src => fixtures}/utils.ts (88%) create mode 100644 tests/integration/module/plugins/babel/babel.test.ts create mode 100644 tests/integration/module/plugins/babel/modern.config.ts create mode 100644 tests/integration/module/plugins/babel/package.json create mode 100644 tests/integration/module/plugins/babel/src/index.js create mode 100644 tests/integration/module/plugins/node-polyfill/modern.config.ts create mode 100644 tests/integration/module/plugins/node-polyfill/node-polyfill.test.ts create mode 100644 tests/integration/module/plugins/node-polyfill/package.json create mode 100644 tests/integration/module/plugins/node-polyfill/src/index.js create mode 100644 tests/integration/module/plugins/polyfill/modern.config.ts create mode 100644 tests/integration/module/plugins/polyfill/package.json create mode 100644 tests/integration/module/plugins/polyfill/polyfill.test.ts create mode 100644 tests/integration/module/plugins/polyfill/src/index.ts delete mode 100644 tests/integration/module/src/__snapshots__/alias.test.ts.snap delete mode 100644 tests/integration/module/src/__snapshots__/designSystem.test.ts.snap delete mode 100644 tests/integration/module/src/__snapshots__/esbuildOptions.test.ts.snap delete mode 100644 tests/integration/module/src/alias.test.ts delete mode 100644 tests/integration/module/src/asset.test.ts delete mode 100644 tests/integration/module/src/constants.ts delete mode 100644 tests/integration/module/src/designSystem.test.ts delete mode 100644 tests/integration/module/src/fixtures/alias/js/bundleless-function.config.ts delete mode 100644 tests/integration/module/src/fixtures/alias/js/bundleless-object.config.ts delete mode 100644 tests/integration/module/src/fixtures/alias/ts/bundleless-function.config.ts delete mode 100644 tests/integration/module/src/fixtures/alias/ts/bundleless-object.config.ts delete mode 100644 tests/integration/module/src/fixtures/designSystem/bundle.config.ts delete mode 100644 tests/integration/module/src/fixtures/designSystem/package.json delete mode 100644 tests/integration/module/src/fixtures/dts/src2/b.ts delete mode 100644 tests/integration/module/src/fixtures/inputFilter/package.json delete mode 100644 tests/integration/module/src/fixtures/inputFilter/src/index.ts delete mode 100644 tests/integration/module/src/fixtures/jsx/automatic-bundleless.config.ts delete mode 100644 tests/integration/module/src/fixtures/jsx/transform-bundleless.config.ts delete mode 100644 tests/integration/module/src/fixtures/redirect/src/index.ts delete mode 100644 tests/integration/module/src/fixtures/target/src/index.js delete mode 100644 tests/integration/module/src/fixtures/target/src/utils.js delete mode 100644 tests/integration/module/src/fixtures/tools/config.ts delete mode 100644 tests/integration/module/src/fixtures/tools/postcss-plugin.js delete mode 100644 tests/integration/module/src/fixtures/tools/src/index.js delete mode 100644 tests/integration/module/src/fixtures/utils/builder/package.json delete mode 100644 tests/integration/module/src/fixtures/watch/package.json delete mode 100644 tests/integration/module/src/fixtures/watch/src/index.js delete mode 100644 tests/integration/module/src/fixtures/watch/src/utils.js delete mode 100644 tests/integration/module/src/inputFilter.test.ts delete mode 100644 tests/integration/module/src/jsx.test.ts delete mode 100644 tests/integration/module/src/redirect.test.ts delete mode 100644 tests/integration/module/src/svgr.test.ts delete mode 100644 tests/integration/module/src/target.test.ts delete mode 100644 tests/integration/module/src/tools.test.ts diff --git a/.changeset/quick-plums-heal.md b/.changeset/quick-plums-heal.md new file mode 100644 index 000000000000..791c6e0ca283 --- /dev/null +++ b/.changeset/quick-plums-heal.md @@ -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 重新实现各插件功能 diff --git a/.changeset/soft-experts-roll.md b/.changeset/soft-experts-roll.md new file mode 100644 index 000000000000..dbbafc10f172 --- /dev/null +++ b/.changeset/soft-experts-roll.md @@ -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 配置。 diff --git a/.eslintignore b/.eslintignore index 178ee421ad4f..a54d212cdcd1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -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 diff --git a/packages/cli/plugin-tailwind/src/cli.ts b/packages/cli/plugin-tailwind/src/cli.ts index abc05e4bf933..5909b5884ec2 100644 --- a/packages/cli/plugin-tailwind/src/cli.ts +++ b/packages/cli/plugin-tailwind/src/cli.ts @@ -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; }, }; }, diff --git a/packages/document/module-doc/docs/en/api/config/build-config.mdx b/packages/document/module-doc/docs/en/api/config/build-config.mdx index e2fb326bc59a..5f565d8e3ef6 100644 --- a/packages/document/module-doc/docs/en/api/config/build-config.mdx +++ b/packages/document/module-doc/docs/en/api/config/build-config.mdx @@ -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 @@ -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 @@ -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. @@ -313,7 +380,6 @@ The dts file generates the relevant configuration, by default it generates. abortOnError: true, distPath: './', only: false, - tsconfigPath: './tsconfig.json', } ``` @@ -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, }, }, }); @@ -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` @@ -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`. @@ -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. @@ -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). @@ -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 @@ -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**: `[]` @@ -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: @@ -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', }, }); ``` diff --git a/packages/document/module-doc/docs/en/guide/advance/in-depth-about-build.md b/packages/document/module-doc/docs/en/guide/advance/in-depth-about-build.md index a1b160ca5dae..901c0ae232ae 100644 --- a/packages/document/module-doc/docs/en/guide/advance/in-depth-about-build.md +++ b/packages/document/module-doc/docs/en/guide/advance/in-depth-about-build.md @@ -12,9 +12,7 @@ If you are not familiar with `buildConfig`, please read [modify-output-product]( In this chapter we'll dive into the use of certain build configurations and understand what happens when the `modern build` command is executed. -## buildConfig - -### `bundle` / `bundleless` +## `bundle` / `bundleless` So first let's understand bundle and bundleless. @@ -33,55 +31,59 @@ bundleless is a single file compilation mode, so for type references and exports In `buildConfig` you can specify whether the current build task is bundle or bundleless by using [`buildConfig.buildType`](/en/api/config/build-config#buildtype). -### `input` / `sourceDir` +## `input` / `sourceDir` -[`buildConfig.input`](/en/api/config/build-config#input) is used to specify the file path or directory path where the source code is read, and its default value differs between bundle and bundleless builds. +[`buildConfig.input`](/api/config/build-config#input) is used to specify the path to a file or directory from which to read the source code, the default value of which varies between bundle and bundleless builds: -- When `buildType: 'bundle'`, `input` defaults to `src/index.(j|t)sx?` -- When `buildType: 'bundleless'`, `input` defaults to `['src']` +- When `buildType: 'bundle'`, `input` defaults to `src/index.(j|t)sx?`. +- When `buildType: 'bundleless'`, `input` defaults to `['src']`. -:::warning -It is recommended that you do not specify multiple source file directories during a bundleless build, as unintended results may occur. bundleless builds with multiple source directories are currently in an unstable stage. -::: +From the default value, we know that **building in bundle mode usually specifies one or more files as the entry point for the build, while building in bundleless mode specifies a directory and uses all the files in that directory as the entry point**. -We know from the defaults: **bundle builds can generally specify a file path as the entry point to the build, while bundleless builds are more expected to use directory paths to find source files**. +[`sourceDir`](/api/config/build-config#sourcedir) is used to specify the source directory, which is **only** related to **the following two elements: + +- Type file generation +- [`outbase`](https://esbuild.github.io/api/#outbase) for specifying the build process -#### Object type of `input` +So we can get its best practices: -In addition to setting `input` to an array, you can also set it to an object during the bundle build process. **By using the object form, we can modify the name of the file that the build artifacts outputs**. So for the following example, `. /src/index.ts` corresponds to the path of the build artifacts file as `. /dist/main.js`. +- **Only specify `input` during the bundle build.** +- **In general, bundleless only needs to specify `sourceDir` (where `input` will be aligned with `sourceDir`).** ** If we want to use the `input` in bundleless, we only need to specify `sourceDir`. + +If you want to convert only some of the files in bundleless, e.g. only the files in the `src/runtime` directory, you need to configure `input`: ```js title="modern.config.ts" import { defineConfig } from '@modern-js/module-tools'; export default defineConfig({ buildConfig: { - input: { - main: ['./src/index.ts'], - }, - outDir: './dist', + input: ['src/runtime'], + sourceDir: 'src', }, }); ``` -The bundleless build process also supports such use, but it is not recommended. +## use swc -#### `sourceDir` +In some scenarios, esbuild is not enough to meet our needs, and we will use swc to do the code conversion. -[`sourceDir`](/en/api/config/build-config#sourcedir) is used to specify the source code directory, which is related to both. +Starting from version **2.36.0**, the Modern.js Module will use swc by default when it comes to the following functionality, but that doesn't mean we don't use esbuild any more, the rest of the functionality will still use esbuild. -- type file generation -- [`outbase`](https://esbuild.github.io/api/#outbase) for specifying the build process +- [transformImport](/api/config/build-config#transformimport) +- [transformLodash](/api/config/build-config#transformlodash) +- [externalHelpers](/api/config/build-config#externalhelpers) +- [format: umd](api/config/build-config#format-umd) +- [target: es5](api/config/build-config#target) +- [emitDecoratorMetadata: true](https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata) -In general: +In fact, we've been using swc for full code conversion since **2.16.0**. However, swc also has some limitations, so we added [sourceType](/api/config/build-config#sourcetype) to turn off swc when the source is formatted as 'commonjs', which isn't really user-intuitive, and the cjs mode of the swc formatted outputs don't have annotate each export name, which can cause problems in node. +So we deprecated this behaviour and went back to the original design - using swc as a supplement only in situations where it was needed. -- **During the bundleless build process, the values of `sourceDir` and `input` should be the same, and their default values are both `src`**. -- It is rarely necessary to use `sourceDir` during the bundle build process. - -### dts +## dts The [`buildConfig.dts`](/en/api/config/build-config#dts) configuration is mainly used for type file generation. -#### Turn off type generation +### Turn off type generation Type generation is turned on by default, if you need to turn it off, you can configure it as follows: @@ -99,7 +101,7 @@ export default defineConfig({ The build speed is generally improved by closing the type file. ::: -#### Build type files +### Build type files With `buildType: 'bundleless'`, type files are generated using the project's `tsc` command to complete production. @@ -108,7 +110,7 @@ The **Modern.js Module also supports bundling of type files**, although care nee - Some third-party dependencies have incorrect syntax that can cause the bundling process to fail. So in this case, you need to exclude such third-party packages manually with [`buildConfig.externals`](/en/api/config/build-config#externals). - It is not possible to handle the case where the type file of a third-party dependency points to a `.ts` file. For example, the `package.json` of a third-party dependency contains something like this: `{"types": ". /src/index.ts"}`. -#### Alias Conversion +### Alias Conversion During the bundleless build process, if an alias appears in the source code, e.g. @@ -124,7 +126,7 @@ Normally, the type files generated with `tsc` will also contain these aliases. H However, there are some cases that cannot be handled at this time.Output types of the form `Promise` cannot be converted at this time. You can discuss it [here](https://github.com/web-infra-dev/modern.js/discussions/4511) -#### Some examples of the use of `dts` +### Some examples of the use of `dts` General usage: @@ -168,72 +170,6 @@ export default defineConfig({ }); ``` -### `buildConfig.define` Usage for different scenarios - -[`buildConfig.define`](/en/api/config/build-config#define) functions somewhat similar to [`webpack.DefinePlugin`](https://webpack.js.org/plugins/define-plugin/). A few usage scenarios are described here. - -#### Environment variable replacement - -```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'); -``` - -#### Global variable replacement - -```js -import { defineConfig } from '@modern-js/module-tools'; -export default defineConfig({ - buildConfig: { - define: { - VERSION: JSON.stringify(require('. /package.json').version || '0.0.0'), - }, - }, -}); -``` - -With the above configuration, we can put the following code. - -```js -// pre-compile code -console.log(VERSION); -``` - -Convert to: - -```js -// post-compile code -console.log('1.0.0'); -``` - -Note, however: 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; -``` - ## Build process When the `modern build` command is executed, the @@ -275,3 +211,42 @@ For `js/ts` build errors, we can tell from the error message. - What is the `format` of the build process - What is the `target` of the build process - The specific error message + +## Debug mode + +From **2.36.0**, For troubleshooting purposes, the Modern.js Module provides a debug mode, which you can enable by adding the DEBUG=module environment variable when executing a build. + +```bash +DEBUG=module modern build +``` + +In debug mode, you'll see more detailed build logs output in Shell, which are mainly process logs: + +```bash +module run beforeBuildTask hooks +6ms +module run beforeBuildTask hooks done +0ms +module [DTS] Build Start +139ms +module [CJS] Build Start +1ms +``` + +In addition, Module provides the ability to debug internal workflows. You can enable more detailed debugging logging by setting the `DEBUG=module:*` environment variable. + +Currently, only `DEBUG=module:resolve` is supported, which allows you to see a detailed log of module resolution within the Module. + +```bash + module:resolve onResolve args: { + path: './src/hooks/misc.ts', + importer: '', + namespace: 'file', + resolveDir: '/Users/bytedance/modern.js/packages/solutions/module-tools', + kind: 'entry-point', + pluginData: undefined +} +0ms + module:resolve onResolve result: { + path: '/Users/bytedance/modern.js/packages/solutions/module-tools/src/hooks/misc.ts', + external: false, + namespace: 'file', + sideEffects: undefined, + suffix: '' +} +0ms +``` diff --git a/packages/document/module-doc/docs/zh/api/config/build-config.mdx b/packages/document/module-doc/docs/zh/api/config/build-config.mdx index 25348db04276..95db06073de3 100644 --- a/packages/document/module-doc/docs/zh/api/config/build-config.mdx +++ b/packages/document/module-doc/docs/zh/api/config/build-config.mdx @@ -212,6 +212,47 @@ export default defineConfig({ - 类型: `boolean` - 默认值: `true` +## banner + +提供为每个 JS , CSS 和 DTS 文件的顶部和底部注入内容的能力。 + +```ts +interface BannerAndFooter { + js?: string; + css?: string; + dts?: string; +} +``` + +- 类型: `BannerAndFooter` +- 默认值: `{}` +- 版本: `v2.36.0` + +例如你想为 JS 和 CSS 文件添加版权信息: + +```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 构建类型,`bundle` 会打包你的代码,`bundleless` 只做代码的转换。 @@ -267,7 +308,7 @@ type Options = { ## define -定义全局变量,会被注入到代码中 +定义全局变量,注入到代码中 - 类型: `Record` - 默认值: `{}` @@ -278,12 +319,48 @@ type Options = { export default defineConfig({ buildConfig: { define: { - VERSION: JSON.stringify('1.0'), + VERSION: JSON.stringify(require('./package.json').version || '0.0.0'), }, }, }); ``` +不过要注意:如果项目是一个 TypeScript 项目,那么你可能需要在项目源代码目录下的 `.d.ts` 文件里增加以下内容: + +> 如果不存在 `d.ts` 文件,则可以手动创建。 + +```ts title="env.d.ts" +declare const YOUR_ADD_GLOBAL_VAR; +``` + +我们也可以进行环境变量替换: + +```js +import { defineConfig } from '@modern-js/module-tools'; +export default defineConfig({ + buildConfig: { + define: { + 'process.env.VERSION': JSON.stringify(process.env.VERSION || '0.0.0'), + }, + }, +}); +``` + +通过上面的配置,我们就可以将下面这段代码: + +```js +// 编译前代码 +console.log(process.env.VERSION); +``` + +在执行 `VERSION=1.0.0 modern build` 的时候,转换为: + +```js +// 编译后代码 +console.log('1.0.0'); +``` + + :::tip 为了防止全局替换替换过度,建议使用时遵循以下两个原则: @@ -292,14 +369,6 @@ export default defineConfig({ ::: -{/* ## disableSwcTransform - -从 2.16.0 版本开始,默认开启 SWC Transform 进行代码转换。如果想要关闭该功能,可以使用该配置。此时仅使用 esbuild Transform。 - -使用 SWC Transform 可以减小辅助函数对构建产物体积的影响。 - -* 类型:`boolean` -* 默认值:`false` */} ## dts @@ -313,7 +382,6 @@ export default defineConfig({ abortOnError: true, distPath: './', only: false, - tsconfigPath: './tsconfig.json', } ``` @@ -397,12 +465,11 @@ export default defineConfig({ ## dts.tsconfigPath -TypeScript 配置文件的路径。 +**废弃**,使用 [tsconfig](#tsconfig) 配置替代。 -- 类型: `string` -- 默认值: `./tsconfig.json` +指定用于生成类型文件的 tsconfig 文件路径。 -```js title="modern.config.ts" +```ts title="modern.config.ts" export default defineConfig({ buildConfig: { dts: { @@ -450,7 +517,7 @@ import RegisterEsbuildPlugin from '@site-docs/components/register-esbuild-plugin 默认情况下,输出的 JS 代码可能会依赖一些辅助函数来支持目标环境或者输出格式,这些辅助函数会被内联在需要它的文件中。 -当在使用 SWC Transform 进行代码转换的时候,可以启动 `externalHelpers` 配置,将内联的辅助函数转换为从外部模块 `@swc/helpers` 导入这些辅助函数。 +使用此配置,将会使用 SWC 对代码进行转换,将内联的辅助函数转换为从外部模块 `@swc/helpers` 导入这些辅助函数。 - 类型:`boolean` - 默认值:`false` @@ -513,6 +580,10 @@ export default defineConfig({ }); ``` +## footer + +同 [banner](#banner) 配置,用于在输出文件末尾添加注释。 + ## format 用于设置 JavaScript 产物输出的格式,其中 `iife` 和 `umd` 只在 `buildType` 为 `bundle` 时生效。 @@ -629,7 +700,6 @@ export default defineConfig({ 上面的配置将打包 `src` 目录下的文件,同时会过滤以 `spec.ts` 为后缀的文件。这在测试文件与源码文件在同一个根目录下的情况会很有用。 - **对象用法:** 当在 bundle 模式下需要修改产物的输出文件名称的时候,可以使用对象形式进行配置。 @@ -651,7 +721,7 @@ export default defineConfig({ 指定 JSX 的编译方式,默认支持 React 17 及更高版本,自动注入 JSX 运行时代码。 -- 类型: `automatic | transform` +- 类型: `automatic | transform | preserve` - 默认值: `automatic` 如果你需要支持 React 16,则可以设置 `jsx` 为 `transform`: @@ -665,6 +735,7 @@ export default defineConfig({ ``` :::tip +如果你不需要转换 JSX ,可以设置 `jsx` 为 `preserve`, 但此时请不要[使用 swc](/guide/advance/in-depth-about-build#使用-swc) 做代码转换。 关于 JSX Transform 的更多说明,可以参考以下链接: - [React Blog - Introducing the New JSX Transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html). @@ -763,6 +834,60 @@ export default { }; ``` +## resolve + +自定义模块解析选项 + +### resolve.mainFields + +package.json 中,在解析包的入口点时尝试的字段列表。 + +- 类型:`string[]` +- 默认值:取决于[platform](#platform) + - node: ['module', 'main'] + - browser: ['module', 'browser', 'main'] +- 版本:`v2.36.0` + +例如,我们想要先加载 `js:source` 字段: + +```js title="modern.config.ts" +export default defineConfig({ + buildConfig: { + resolve: { + mainFields: ['js:source', 'module', 'main'], + } + }, +}); +``` + +:::warning +`resolve.mainFields` 比 package.json 中 exports 字段的优先级低,如果一个入口点从 exports 成功解析,`resolve.mainFields` 将被忽略。 +::: + +### resolve.jsExtentions + +支持隐式文件扩展名 + +- 类型: `string[]` +- 默认值: `['.jsx', '.tsx', '.js', '.ts', '.json']` +- 版本:`v2.36.0` + + +对于 css 文件,请不要使用隐式文件扩展名,目前 Module 仅支持 ['.less', '.css', '.sass', '.scss'] 后缀。 + +Node 的解析算法不会将 `.mjs` 和 `cjs` 视为隐式文件扩展名,因此这里默认也不会,但是可以通过更改此配置来包含: + +```js title="modern.config.ts" +export default defineConfig({ + buildConfig: { + resolve: { + jsExtentions: ['.mts', 'ts'] + } + }, +}); +``` + + ## sideEffects 配置模块的副作用 @@ -823,6 +948,10 @@ export default defineConfig({ ## sourceType +:::warning +已废弃,此配置不会产生任何影响。 +::: + 设置源码的格式。默认情况下,会将源码作为 EsModule 进行处理。当源码使用的是 CommonJS 的时候,需要设置 `commonjs`。 - 类型:`'commonjs' | 'module'` @@ -1186,7 +1315,7 @@ export default defineConfig({ ## transformImport -提供与 babel-plugin-import 等价的能力和配置,基于 SWC 实现。 +提供与 babel-plugin-import 等价的能力和配置,基于 SWC 实现,使用此配置,将会使用 SWC 对代码进行转换。 - 类型:`object[]` - 默认值:`[]` @@ -1214,11 +1343,12 @@ export default defineConfig({ ## transformLodash 是否模块化 [lodash](https://www.npmjs.com/package/lodash) 的导入,删除未使用的 lodash 模块,从而减少 lodash 代码体积。这项优化基于 [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash) 和 [swc-plugin-lodash](https://github.com/web-infra-dev/swc-plugins/tree/main/crates/plugin_lodash) 实现。 +使用此配置,将会使用 SWC 对代码进行转换。 - 类型:`boolean` -- 默认值:`true` +- 默认值:`false` -该选项默认开启,Modern.js Module 会自动将 lodash 的代码引用指向子路径。 +当开启此选项时,Modern.js Module 会自动将 lodash 的代码引用指向子路径。 比如: @@ -1240,12 +1370,18 @@ const addOne = _add(1); _map([1, 2, 3], addOne); ``` -然而有时候 lodash 的 import 转换可能会生成不符合预期的代码,此时你可以手动关闭这项优化: +## tsconfig + +TypeScript 配置文件的路径。 + +- 类型: `string` +- 默认值: `tsconfig.json` +- 版本: `v2.36.0` ```js title="modern.config.ts" export default defineConfig({ buildConfig: { - transformLodash: false, + tsconfig: 'tsconfig.build.json', }, }); ``` diff --git a/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md b/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md index e7af2dd9bdda..0ee05cc1a210 100644 --- a/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md +++ b/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md @@ -12,9 +12,7 @@ sidebar_position: 1 而在本章里我们将要深入理解某些构建配置的作用以及了解执行 `modern build` 命令的时候发生了什么。 -## buildConfig - -### `bundle` / `bundleless` +## `bundle` / `bundleless` 那么首先我们来了解一下 bundle 和 bundleless。 @@ -33,34 +31,59 @@ bundleless 是单文件编译模式,因此对于类型的引用和导出你需 在 `buildConfig` 中可以通过 [`buildConfig.buildType`](/api/config/build-config#buildtype) 来指定当前构建任务是 bundle 还是 bundleless。 -### `input` / `sourceDir` +## `input` / `sourceDir` [`buildConfig.input`](/api/config/build-config#input) 用于指定读取源码的文件路径或者目录路径,其默认值在 bundle 和 bundleless 构建过程中有所不同: - 当 `buildType: 'bundle'` 的时候,`input` 默认值为 `src/index.(j|t)sx?` - 当 `buildType: 'bundleless'` 的时候,`input` 默认值为 `['src']` -:::warning -建议不要在 bundleless 构建过程中指定多个源码文件目录,这可能会导致产物里的相对路径不正确。 -::: +从默认值上我们可以知道:**使用 bundle 模式构建时一般指定一个或多个文件作为构建的入口,而使用 bundleless 构建则是指定一个目录,将目录下所有文件作为入口**。 -从默认值上我们可以知道:**bundle 构建一般可以指定文件路径作为构建的入口,而 bundleless 构建则更期望使用目录路径寻找源文件**。 - -[`sourceDir`](/api/config/build-config#sourcedir) 用于指定源码目录,它主要与以下两个内容有关系: +[`sourceDir`](/api/config/build-config#sourcedir) 用于指定源码目录,它**只与**以下两个内容有关系: - 类型文件生成 - 指定构建过程中的 [`outbase`](https://esbuild.github.io/api/#outbase) -一般来说: +因此我们可以得到其最佳实践: + +- **在 bundle 构建过程中,只能指定 `input` 。** +- **一般情况下,bundleless 只需要指定 `sourceDir`(此时 `input` 会与 `sourceDir` 保持一致)。** + +如果我们想要在 bundleless 里只对一部分文件进行转换,例如只需要转换 `src/runtime` 目录的文件,此时需要配置 `input`: + +```js title="modern.config.ts" +import { defineConfig } from '@modern-js/module-tools'; + +export default defineConfig({ + buildConfig: { + input: ['src/runtime'], + sourceDir: 'src', + }, +}); +``` + +## 使用 swc + +在部分场景下,esbuild 不足以满足我们的需求,此时我们会使用 swc 来做代码转换。 + +从 **2.36.0** 版本开始,涉及到以下功能时,Modern.js Module 默认会使用 swc ,但不这意味着不使用 esbuild 了,其余功能还是使用 esbuild: + +- [transformImport](/api/config/build-config#transformimport) +- [transformLodash](/api/config/build-config#transformlodash) +- [externalHelpers](/api/config/build-config#externalhelpers) +- [format: umd](api/config/build-config#format-umd) +- [target: es5](api/config/build-config#target) +- [emitDecoratorMetadata: true](https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata) -- **在 bundleless 构建过程中,`sourceDir` 与 `input` 的值要保持一致,它们的默认值都是 `src`**。 -- 在 bundle 构建过程中,无需使用 `sourceDir`。 +事实上,我们在 **2.16.0** 开始全量使用 swc 进行代码转换。不过 swc 同样也存在一些限制,为此我们添加了 [sourceType](/api/config/build-config#sourcetype) 配置,当源码格式为 'commonjs' 时关闭 swc, 但这种方式并不符合用户直觉,另外,swc 格式化输出的 cjs 模式没有给每个导出名称添加注释,这在 node 中使用可能会带来一些问题。 +因为我们废弃了此行为,回到了最初的设计 - 只在需要的场景下使用 swc 作为补充。 -### dts +## 类型文件生成 [`buildConfig.dts`](/api/config/build-config#dts) 配置主要用于类型文件的生成。 -#### 关闭类型生成 +### 关闭类型生成 默认情况下类型生成功能是开启的,如果需要关闭的话,可以按照如下配置: @@ -78,7 +101,7 @@ export default defineConfig({ 关闭类型文件后,一般来说构建速度会有所提升。 ::: -#### 打包类型文件 +### 打包类型文件 在 `buildType: 'bundleless'` 的时候,类型文件的生成是使用项目的 `tsc` 命令来完成生产。 @@ -87,7 +110,7 @@ export default defineConfig({ - 一些第三方依赖存在错误的语法会导致打包过程失败。因此对于这种情况,需要手动通过 [`buildConfig.externals`](/api/config/build-config#externals) 将这类第三方包排除。 - 对于第三方依赖的类型文件指向的是一个 `.ts` 文件的情况,目前无法处理。比如第三方依赖的 `package.json` 中存在这样的内容: `{"types": "./src/index.ts"}`。 -#### 别名转换 +### 别名转换 在 bundleless 构建过程中,如果源代码中出现了别名,例如: @@ -103,7 +126,7 @@ import utils from '@common/utils'; 然而也存在一些情况,目前还无法处理,例如 `Promise` 这样形式的输出类型目前无法进行转换。 对于这种情况的解决办法,可以参与[讨论](https://github.com/web-infra-dev/modern.js/discussions/4511)。 -#### 一些示例 +### 一些示例 ```js import { defineConfig } from '@modern-js/module-tools'; @@ -143,72 +166,6 @@ export default defineConfig({ }); ``` -### `define` - -[`buildConfig.define`](/api/config/build-config#define) 功能有些类似 [`webpack.DefinePlugin`](https://webpack.js.org/plugins/define-plugin/)。这里介绍几个使用场景: - -#### 环境变量替换 - -```js -import { defineConfig } from '@modern-js/module-tools'; -export default defineConfig({ - buildConfig: { - define: { - 'process.env.VERSION': JSON.stringify(process.env.VERSION || '0.0.0'), - }, - }, -}); -``` - -通过上面的配置,我们就可以将下面这段代码: - -```js -// 编译前代码 -console.log(process.env.VERSION); -``` - -在执行 `VERSION=1.0.0 modern build` 的时候,转换为: - -```js -// 编译后代码 -console.log('1.0.0'); -``` - -#### 全局变量替换 - -```js -import { defineConfig } from '@modern-js/module-tools'; -export default defineConfig({ - buildConfig: { - define: { - VERSION: JSON.stringify(require('./package.json').version || '0.0.0'), - }, - }, -}); -``` - -通过上面的配置,我们就可以将下面这段代码: - -```js -// 编译前代码 -console.log(VERSION); -``` - -转换为: - -```js -// 编译后代码 -console.log('1.0.0'); -``` - -不过要注意:如果项目是一个 TypeScript 项目,那么你可能需要在项目源代码目录下的 `.d.ts` 文件里增加以下内容: - -> 如果不存在 `d.ts` 文件,则可以手动创建。 - -```ts title="env.d.ts" -declare const YOUR_ADD_GLOBAL_VAR; -``` - ## 构建过程 当执行 `modern build` 命令的时候,会发生 @@ -250,3 +207,42 @@ bundle DTS failed: - 报错的 `format` - 报错的 `target` - 其他具体报错信息 + +## 调试模式 + +从 **2.36.0** 版本开始,为了便于排查问题,Modern.js Module 提供了调试模式,你可以在执行构建时添加 DEBUG=module 环境变量来开启调试模式。 + +```bash +DEBUG=module modern build +``` + +调试模式下,你会看到 Shell 中输出更详细的构建日志,这主要以流程日志为主: + +```bash +module run beforeBuildTask hooks +6ms +module run beforeBuildTask hooks done +0ms +module [DTS] Build Start +139ms +module [CJS] Build Start +1ms +``` + +另外,Module 还提供了调试内部工作流程的能力。你可以通过设置环境变量 `DEBUG=module:*` 来开启更详细的调试日志: + +目前只支持了 `DEBUG=module:resolve`,可以查看 Module 内部模块解析的详细日志: + +```bash + module:resolve onResolve args: { + path: './src/hooks/misc.ts', + importer: '', + namespace: 'file', + resolveDir: '/Users/bytedance/modern.js/packages/solutions/module-tools', + kind: 'entry-point', + pluginData: undefined +} +0ms + module:resolve onResolve result: { + path: '/Users/bytedance/modern.js/packages/solutions/module-tools/src/hooks/misc.ts', + external: false, + namespace: 'file', + sideEffects: undefined, + suffix: '' +} +0ms +``` diff --git a/packages/document/module-doc/docs/zh/plugins/official-list/plugin-banner.mdx b/packages/document/module-doc/docs/zh/plugins/official-list/plugin-banner.mdx index 28fdcb6e8048..2703346b0865 100644 --- a/packages/document/module-doc/docs/zh/plugins/official-list/plugin-banner.mdx +++ b/packages/document/module-doc/docs/zh/plugins/official-list/plugin-banner.mdx @@ -2,6 +2,11 @@ 提供为每个 JS 和 CSS 文件的顶部和底部注入内容的能力。 +:::tip +从 `@modern-js/module-tools` v2.36.0 版本开始,该插件功能内置在 Modern.js Module 中,由 [`banner`](/api/config/build-config#banner) 和 [`footer`](/api/config/build-config#footer) +配置提供。 +::: + ## 快速开始 ### 安装 diff --git a/packages/generator/generators/base-generator/package.json b/packages/generator/generators/base-generator/package.json index aa4fa8b43fa9..25fd5cb7c358 100644 --- a/packages/generator/generators/base-generator/package.json +++ b/packages/generator/generators/base-generator/package.json @@ -34,6 +34,7 @@ "@modern-js/codesmith-api-app": "2.2.5", "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/bff-generator/package.json b/packages/generator/generators/bff-generator/package.json index 49a08ee7db58..84383efc556b 100644 --- a/packages/generator/generators/bff-generator/package.json +++ b/packages/generator/generators/bff-generator/package.json @@ -36,6 +36,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", "@modern-js/generator-utils": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/changeset-generator/package.json b/packages/generator/generators/changeset-generator/package.json index 9ed887dfab6e..ca5f3fa4230c 100644 --- a/packages/generator/generators/changeset-generator/package.json +++ b/packages/generator/generators/changeset-generator/package.json @@ -32,6 +32,7 @@ "@modern-js/codesmith": "2.2.5", "@modern-js/codesmith-api-app": "2.2.5", "@modern-js/generator-common": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/dependence-generator/package.json b/packages/generator/generators/dependence-generator/package.json index d0ad7b104299..c62d49d3c8ca 100644 --- a/packages/generator/generators/dependence-generator/package.json +++ b/packages/generator/generators/dependence-generator/package.json @@ -35,6 +35,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/generator-generator/package.json b/packages/generator/generators/generator-generator/package.json index 338414db0ffc..3624456ce13c 100644 --- a/packages/generator/generators/generator-generator/package.json +++ b/packages/generator/generators/generator-generator/package.json @@ -36,6 +36,7 @@ "@modern-js/generator-utils": "workspace:*", "@modern-js/module-generator": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/module-generator/package.json b/packages/generator/generators/module-generator/package.json index e6a15de5dee2..30c99aa1587b 100644 --- a/packages/generator/generators/module-generator/package.json +++ b/packages/generator/generators/module-generator/package.json @@ -38,6 +38,7 @@ "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", "@modern-js/packages-generator": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/module-test-generator/package.json b/packages/generator/generators/module-test-generator/package.json index 0f5c0b3c905e..41f0e2485e31 100644 --- a/packages/generator/generators/module-test-generator/package.json +++ b/packages/generator/generators/module-test-generator/package.json @@ -36,6 +36,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/monorepo-generator/package.json b/packages/generator/generators/monorepo-generator/package.json index e3f8b585bb14..15130803293b 100644 --- a/packages/generator/generators/monorepo-generator/package.json +++ b/packages/generator/generators/monorepo-generator/package.json @@ -38,6 +38,7 @@ "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", "@modern-js/packages-generator": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/mwa-generator/package.json b/packages/generator/generators/mwa-generator/package.json index 7d2e25d90138..a807a94a455a 100644 --- a/packages/generator/generators/mwa-generator/package.json +++ b/packages/generator/generators/mwa-generator/package.json @@ -39,6 +39,7 @@ "@modern-js/packages-generator": "workspace:*", "@modern-js/rspack-generator": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/packages-generator/package.json b/packages/generator/generators/packages-generator/package.json index a42804e88884..f328f0ab1365 100644 --- a/packages/generator/generators/packages-generator/package.json +++ b/packages/generator/generators/packages-generator/package.json @@ -34,6 +34,7 @@ "@modern-js/codesmith-api-json": "2.2.5", "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/router-v5-generator/package.json b/packages/generator/generators/router-v5-generator/package.json index 62b80db31597..65c7df4083d5 100644 --- a/packages/generator/generators/router-v5-generator/package.json +++ b/packages/generator/generators/router-v5-generator/package.json @@ -35,6 +35,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/rspack-generator/package.json b/packages/generator/generators/rspack-generator/package.json index e63452fd7abf..51940ba2331e 100644 --- a/packages/generator/generators/rspack-generator/package.json +++ b/packages/generator/generators/rspack-generator/package.json @@ -35,6 +35,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/server-generator/package.json b/packages/generator/generators/server-generator/package.json index b0142b158868..98fcab10fbcd 100644 --- a/packages/generator/generators/server-generator/package.json +++ b/packages/generator/generators/server-generator/package.json @@ -36,6 +36,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/dependence-generator": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/ssg-generator/package.json b/packages/generator/generators/ssg-generator/package.json index 81f35747cf4e..cc8947946617 100644 --- a/packages/generator/generators/ssg-generator/package.json +++ b/packages/generator/generators/ssg-generator/package.json @@ -35,6 +35,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/storybook-generator/package.json b/packages/generator/generators/storybook-generator/package.json index 214db9f82a90..a573a6086812 100644 --- a/packages/generator/generators/storybook-generator/package.json +++ b/packages/generator/generators/storybook-generator/package.json @@ -36,6 +36,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/tailwindcss-generator/package.json b/packages/generator/generators/tailwindcss-generator/package.json index 0bdc0471385a..e14db8a7d40a 100644 --- a/packages/generator/generators/tailwindcss-generator/package.json +++ b/packages/generator/generators/tailwindcss-generator/package.json @@ -34,6 +34,7 @@ "@modern-js/dependence-generator": "workspace:*", "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/test-generator/package.json b/packages/generator/generators/test-generator/package.json index a5b56199d138..7aa111892b6c 100644 --- a/packages/generator/generators/test-generator/package.json +++ b/packages/generator/generators/test-generator/package.json @@ -36,6 +36,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/generators/upgrade-generator/package.json b/packages/generator/generators/upgrade-generator/package.json index 3c1ab8f8b73d..c876e74012a2 100644 --- a/packages/generator/generators/upgrade-generator/package.json +++ b/packages/generator/generators/upgrade-generator/package.json @@ -35,6 +35,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-utils": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@types/jest": "^29", diff --git a/packages/generator/plugins/generator-plugin/package.json b/packages/generator/plugins/generator-plugin/package.json index 75e5c8462ebb..450b31d11a2c 100644 --- a/packages/generator/plugins/generator-plugin/package.json +++ b/packages/generator/plugins/generator-plugin/package.json @@ -38,6 +38,7 @@ "@modern-js/generator-common": "workspace:*", "@modern-js/generator-plugin": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", + "@modern-js/utils": "workspace:*", "@types/jest": "^29", "@types/node": "^14", "typescript": "^5", diff --git a/packages/libuild/libuild-core/.eslintrc.cjs b/packages/libuild/libuild-core/.eslintrc.cjs deleted file mode 100644 index 1c2d3003e024..000000000000 --- a/packages/libuild/libuild-core/.eslintrc.cjs +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - root: true, - extends: ['@modern-js/eslint-config'], - ignorePatterns: ['scripts/*.ts'], - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - rules: { - // https://eslint.org/docs/rules/complexity - complexity: ['warn', { max: 50 }], - treatUndefinedAsUnspecified: 0, - }, -}; diff --git a/packages/libuild/libuild-core/.gitignore b/packages/libuild/libuild-core/.gitignore deleted file mode 100644 index 242b4e6efdda..000000000000 --- a/packages/libuild/libuild-core/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -dist -lib -temp -*.cpuprofile diff --git a/packages/libuild/libuild-core/.mocharc.js b/packages/libuild/libuild-core/.mocharc.js deleted file mode 100644 index 3f1887f1e01b..000000000000 --- a/packages/libuild/libuild-core/.mocharc.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); - -module.exports = { - require: require.resolve('tsm'), - extensions: ['.ts', '.tsx', '.js', '.jsx'], - spec: [path.join(__dirname, './**/*.{spec,test}.*')], -}; diff --git a/packages/libuild/libuild-core/CHANGELOG.md b/packages/libuild/libuild-core/CHANGELOG.md deleted file mode 100644 index d80ed5a201e1..000000000000 --- a/packages/libuild/libuild-core/CHANGELOG.md +++ /dev/null @@ -1,47 +0,0 @@ -# @modern-js/libuild - -## 2.35.1 - -## 2.35.0 - -### Patch Changes - -- 28128ca: refactor(builder): migrate to tsconfig-paths-webpack-plugin - - refactor(builder): 迁移至 tsconfig-paths-webpack-plugin - -## 2.34.0 - -## 2.33.1 - -## 2.33.0 - -## 2.32.1 - -## 2.32.0 - -## 2.31.2 - -## 2.31.1 - -## 2.31.0 - -### Patch Changes - -- 1882366: chore(deps): bump build dependencies - - chore(deps): 升级构建相关依赖 - -## 2.30.0 - -### Patch Changes - -- 05fa4d5: ci: fix build scripts for libuild in windows - ci: 修复在 windows 下的 libuild 构建脚本 -- 7cb7b24: chore(libuild): bump typescript v5 and some other devDependencies - - chore(libuild): 升级 typescript v5 和其他 devDependencies - -- 3e67a4e: chore(libuild): remove some unused dev dependencies - - chore(libuild): 移除一些无用的 dev dependencies diff --git a/packages/libuild/libuild-core/LICENSE.md b/packages/libuild/libuild-core/LICENSE.md deleted file mode 100644 index 39e3c5971226..000000000000 --- a/packages/libuild/libuild-core/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021-present Modern.js - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/libuild/libuild-core/README.md b/packages/libuild/libuild-core/README.md deleted file mode 100644 index 0c42484a5fb9..000000000000 --- a/packages/libuild/libuild-core/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Libuild - -A Builder for Modern.js Module. - -[MIT](./LICENSE.md) diff --git a/packages/libuild/libuild-core/api-extractor.json b/packages/libuild/libuild-core/api-extractor.json deleted file mode 100644 index 6ecbe3239183..000000000000 --- a/packages/libuild/libuild-core/api-extractor.json +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Config file for API Extractor. For more info, please visit: https://api-extractor.com - */ -{ - "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "/lib/index.d.ts", - "bundledPackages": ["tapable", "sass", "source-map"], - "apiReport": { - "enabled": true, - "reportFolder": "/temp/" - }, - "docModel": { - "enabled": true - }, - "tsdocMetadata": { - "enabled": false - }, - "messages": { - "compilerMessageReporting": { - "default": { - "logLevel": "warning" - } - }, - "extractorMessageReporting": { - "default": { - "logLevel": "warning" - }, - "ae-missing-release-tag": { - "logLevel": "none" - } - }, - "tsdocMessageReporting": { - "default": { - "logLevel": "none" - }, - "tsdoc-undefined-tag": { - "logLevel": "none" - } - } - }, - "dtsRollup": { - "enabled": true, - "untrimmedFilePath": "/dist/index.d.ts" - }, - "compiler": { - "tsconfigFilePath": "/tsconfig.build.json" - } -} diff --git a/packages/libuild/libuild-core/package.json b/packages/libuild/libuild-core/package.json deleted file mode 100644 index db94640de2b1..000000000000 --- a/packages/libuild/libuild-core/package.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "name": "@modern-js/libuild", - "version": "2.35.1", - "description": "A tool for building modern JavaScript libraries", - "keywords": [ - "modern", - "modern.js", - "javascript", - "library", - "build", - "tool" - ], - "repository": "modern-js-dev/libuild", - "license": "MIT", - "main": "dist/index.js", - "source": "src/index.ts", - "types": "dist/index.d.ts", - "files": [ - "dist", - "config", - "!dist/*.map", - "cli.js" - ], - "scripts": { - "build": "rimraf dist lib *.tsbuildinfo && npm run typecheck && npm run build:local", - "build:local": "node -r tsm scripts/build.ts", - "prepublishOnly": "npm run build", - "typecheck": "tsc -b tsconfig.build.json", - "watch": "npm run typecheck && npm run build:local -- --watch", - "test": "tsd && mocha" - }, - "dependencies": { - "esbuild": "0.17.19", - "postcss": "8.4.27", - "source-map": "0.7.4", - "source-map-support": "0.5.20", - "style-inject": "0.3.0", - "terser": "5.19.2", - "@ast-grep/napi": "0.1.13", - "sucrase": "3.29.0" - }, - "devDependencies": { - "@ampproject/remapping": "1.0.2", - "@babel/code-frame": "^7.22.13", - "@microsoft/api-extractor": "7.36.4", - "@modern-js/libuild-utils": "workspace:*", - "@rollup/pluginutils": "4.1.1", - "@types/babel__code-frame": "7.0.3", - "@types/convert-source-map": "1.5.2", - "@types/deep-eql": "4.0.0", - "@types/fs-extra": "9.0.13", - "@types/less": "3.0.3", - "@types/mime-types": "2.1.1", - "@types/mocha": "9.0.0", - "@types/node": "12.20.42", - "@types/picomatch": "2.3.0", - "@types/rimraf": "3.0.2", - "@types/sass": "1.43.1", - "@types/source-map-support": "0.5.4", - "@types/stack-trace": "0.0.30", - "@types/yargs": "17.0.4", - "chalk": "4.1.0", - "chokidar": "3.5.2", - "convert-source-map": "1.8.0", - "deep-eql": "4.1.0", - "enhanced-resolve": "5.8.3", - "error-stack": "1.0.3", - "es-module-lexer": "0.9.3", - "fs-extra": "10.0.0", - "import-lazy": "4.0.0", - "mime-types": "2.1.33", - "mocha": "9.1.3", - "picomatch": "2.3.0", - "postcss-load-config": "3.1.4", - "postcss-modules": "4.3.0", - "rimraf": "3.0.2", - "stack-trace": "1.0.0-pre1", - "strip-ansi": "7.0.1", - "tapable": "2.2.1", - "tsconfig-paths": "4.1.1", - "tsconfig-paths-webpack-plugin": "4.1.0", - "tsd": "0.19.1", - "tsm": "2.3.0", - "typescript": "^5", - "yargs": "17.2.1", - "magic-string": "0.26.4", - "safe-identifier": "0.4.2", - "micromatch": "4.0.5", - "glob": "8.1.0", - "@types/micromatch": "4.0.2", - "@types/glob": "8.0.1" - }, - "sideEffects": false, - "tsd": { - "directory": "test/dts" - } -} diff --git a/packages/libuild/libuild-core/scripts/build.ts b/packages/libuild/libuild-core/scripts/build.ts deleted file mode 100644 index e2d1b0356b08..000000000000 --- a/packages/libuild/libuild-core/scripts/build.ts +++ /dev/null @@ -1,238 +0,0 @@ -import { Plugin, transform, build, context } from 'esbuild'; -import * as esbuild from 'esbuild'; -import rimraf from 'rimraf'; -import yargs from 'yargs'; -import path from 'path'; -import fse from 'fs-extra'; -import { resolvePathAndQuery } from '@modern-js/libuild-utils'; -import { Extractor, ExtractorConfig } from '@microsoft/api-extractor'; -import remapping from '@ampproject/remapping'; - -let rebuildCnt = 0; - -const outdir = path.resolve(__dirname, '../dist'); - -async function run() { - const args = await yargs - .option('watch', { - type: 'boolean', - }) - .option('splitting', { - type: 'boolean', - default: true, - }) - .parse(process.argv); - - function clean() { - rimraf.sync('dist'); - } - clean(); - function splitPlugin(): Plugin { - return { - name: 'esm2cjs', - setup(build) { - let startTime: number; - - build.onStart(() => { - startTime = Date.now(); - console.log('[Libuild]> Begin build'); - }); - - build.onEnd(async (result) => { - if (!result.outputFiles) { - return; - } - await fse.ensureDir(outdir); - - for (const item of result.outputFiles) { - if (item.path.endsWith('.js')) { - const originSourcemap = result.outputFiles.find((f) => f.path === `${item.path}.map`)!.text; - const needSourcemap = JSON.parse(originSourcemap)?.sources.length > 0; - const transformResult = await transform(item.text, { - format: 'cjs', - sourcemap: needSourcemap, - sourcesContent: false, - }); - - if (needSourcemap) { - const resultMap = remapping([transformResult.map, originSourcemap], () => null); - await fse.promises.writeFile(`${item.path}.map`, JSON.stringify(resultMap)); - } - - const filename = path.basename(item.path); - const sourcemapURL = needSourcemap ? `//# sourceMappingURL=${filename}.map` : ''; - await fse.promises.writeFile(item.path, `${transformResult.code}${sourcemapURL}`); - } else if (item.path.endsWith('.js.map')) { - // - } else { - await fse.promises.writeFile(item.path, item.contents); - } - } - - const endTime = Date.now(); - console.log(`[Libuild]> Build completed, build cost ${endTime - startTime}ms, build count:`, ++rebuildCnt); - }); - }, - }; - } - function enhancedResolvePlugin(): Plugin { - return { - name: 'enhanced-resolve-loader', - setup(build) { - build.onResolve({ filter: /^enhanced-resolve/ }, (args) => { - const baseName = path.join(__dirname, '..'); - const subPath = args.path.replace('enhanced-resolve', ''); - - let realPath = require.resolve('enhanced-resolve', { paths: [baseName] }); - if (subPath) { - realPath = realPath.replace(/([\\\/]lib[\\\/].*)$/, `${subPath}.js`); - } - return { - path: realPath, - pluginData: {}, - }; - }); - build.onLoad({ filter: /enhanced-resolve\/lib\/createInnerCallback\.js$/ }, async (args) => { - // Hack for `tsconfig-paths-webpack-plugin` - // Because of `createInnerCallback` is deprecate from `enhanced-resolve` - return { - contents: `module.exports = function(callback) { return callback }`, - loader: 'ts', - }; - }); - }, - }; - } - function rawPlugin(): Plugin { - return { - name: 'raw-loader', - setup(build) { - build.onResolve({ filter: /.*/ }, (args) => { - const { query, originalFilePath } = resolvePathAndQuery(args.path); - - if (query.raw || query.code) { - const realPath = require.resolve(originalFilePath, { paths: [args.resolveDir] }); - return { - path: realPath, - pluginData: { - code: query.code, - raw: query.raw, - }, - }; - } - }); - build.onLoad({ filter: /.*/ }, async (args) => { - if (!(args.pluginData?.code || args.pluginData?.raw)) { - return; - } - let contents = fse.readFileSync(args.path, 'utf-8').replace(/# sourceMappingURL=(.+?\.map)/g, '# $1'); - if (args.pluginData?.code) { - const result = await esbuild.build({ - entryPoints: [args.path], - bundle: true, - write: false, - format: 'iife', - outfile: 'code.js', - }); - contents = result.outputFiles[0].text; - } - return { - contents: `module.exports = ${JSON.stringify(contents)}`, - loader: 'ts', - }; - }); - }, - }; - } - function workerPlugin(): Plugin { - return { - name: 'worker-url', - setup(build) { - build.onResolve({ filter: /\?worker/ }, (args) => { - return { - path: path.resolve(args.resolveDir, args.path.split('?')[0]), - namespace: 'worker-url', - pluginData: {}, - }; - }); - build.onLoad({ filter: /.*/, namespace: 'worker-url' }, (args) => { - const baseName = path.join(__dirname, '..'); - const workerName = path.relative(baseName, args.path).split('.')[0].split('/').join('-'); - esbuild.build({ - entryPoints: [args.path], - platform: 'node', - target: 'node12', - bundle: true, - sourcemap: true, - outfile: `./dist/${workerName}.js`, - }); - return { - contents: `module.exports = require.resolve(${JSON.stringify( - `./${workerName}.js` - )}, { paths: [__dirname] })`, - loader: 'ts', - }; - }); - }, - }; - } - - const config: esbuild.BuildOptions = { - entryPoints: [path.resolve(__dirname, '../src/index.ts')], - target: 'node12', - sourcemap: args.splitting ? 'external' : true, - bundle: true, - platform: 'node', - format: args.splitting ? 'esm' : 'cjs', - write: !args.splitting, - splitting: args.splitting, - sourcesContent: args.splitting, - mainFields: ['source', 'main', 'module'], - outdir, - external: [ - 'esbuild', - 'terser', - 'postcss', - 'less', - 'pnpapi', - 'fsevents', - 'source-map', - 'source-map-support', - 'typescript', - '@ast-grep/napi', - ], - plugins: [ - args.splitting && splitPlugin(), - workerPlugin(), - rawPlugin(), - enhancedResolvePlugin(), - ].filter(Boolean) as Plugin[], - }; - - if (args.watch) { - await (await context(config)).watch(); - } else { - await build(config); - } - - // extract types - const apiExtractorJsonPath: string = path.join(__dirname, '../api-extractor.json'); - const extractorConfig = ExtractorConfig.loadFileAndPrepare(apiExtractorJsonPath); - const extractorResult = Extractor.invoke(extractorConfig, { - localBuild: true, - showVerboseMessages: true, - }); - - if (extractorResult.succeeded) { - console.log(`API Extractor completed successfully`); - process.exitCode = 0; - } else { - console.error( - `API Extractor completed with ${extractorResult.errorCount} errors` + - ` and ${extractorResult.warningCount} warnings` - ); - process.exitCode = 1; - } -} - -run(); diff --git a/packages/libuild/libuild-core/src/bundler/adapter.ts b/packages/libuild/libuild-core/src/bundler/adapter.ts deleted file mode 100644 index b2a8c5e9b420..000000000000 --- a/packages/libuild/libuild-core/src/bundler/adapter.ts +++ /dev/null @@ -1,405 +0,0 @@ -import path from 'path'; -import fs from 'fs-extra'; -import pm from 'picomatch'; -import { Loader, Plugin, BuildResult } from 'esbuild'; -import { resolvePathAndQuery } from '@modern-js/libuild-utils'; -import { ILibuilder, BuildConfig } from '../types'; -import { normalizeSourceMap } from '../utils'; -import { DATAURL_JAVASCRIPT_PATTERNS } from '../constants/regExp'; -import { loaderMap } from '../constants/loader'; -import { installResolve } from './resolve'; - -type IEntry = { - /** - * Entry name - */ - name: string; - /** - * Entry path - */ - path: string; - /** - * Chunks name. - */ - chunkNames: string[]; -}; - -/** - * This is a hack to deal with the inconsit behavior between rollup and esbuild - * rollup resolveId support return non absolute path - * esbuild onResolve doesn't support return no absolute path for non file namespace - * so we need to convert rollup's resolve result to non file namespace to avoid esbuild crash - * and support rollup's plugin's virtual module - * @example - * rollup's plugin - * { - * resolveId(id){ - * if(id === 'virtual-path'){ - * return id; // this will crash esbuild - * } - * } - * } - * convert it to esubild plugin - * { - * setup(build){ - * build.onResolve({filter:/.*\/},args => { - * if(args.path === 'virtual-path'){ - * return { - * path: id, - * namespace: VirtualPathProxyNamespace - * } - * } - * }) - * } - * } - */ -const VirtualPathProxyNamespace = 'VirtualPathProxyNamespace'; -/** - * some plugin may return virtualModuleId from onResolve, which will cause problem for other plugin - * which may treat id as real fileSystemPath, wo wee need to convert it to other namspece - */ -const LibuildVirtualNamespace = 'libuild:virtual'; -/** - * esbuld's external will keep import statement as import|require statement, which - * is ok for node environment but will cause problem for browser environment(lack of commonjs runtime supports) - * so we need to support features like rollup's globals, which will convert an module id to global variable - * @example - * @libuild.config.ts - * { - * externals: { - * 'jquery': '$' - * } - * } - * which will convert this code - * import jq from 'jquery' - * to - * const jq = globalThis['$'] - */ -const LibuildGlobalNamespace = 'libuild:globals'; - -async function internalLoad(id: string) { - return fs.promises.readFile(id); -} - -/** - * proxy libuild hooks to esbuild - */ -export const adapterPlugin = (compiler: ILibuilder): Plugin => { - return { - name: 'libuild:adapter', - setup(build) { - build.onStart(async () => { - compiler.config.logger.debug('onStart'); - compiler.resolve = installResolve(compiler); - compiler.outputChunk = new Map(); - await compiler.hooks.startCompilation.promise(); - }); - build.onResolve({ filter: /.*/ }, async args => { - compiler.config.logger.debug('onResolve', args.path); - - const { query } = resolvePathAndQuery(args.path); - if (query.virtual) { - return { - path: args.path, - namespace: LibuildVirtualNamespace, - }; - } - /** - * isolate plugin between libuild and other namespace - */ - if ( - args.namespace !== 'file' && - args.namespace !== VirtualPathProxyNamespace && - args.namespace !== LibuildVirtualNamespace - ) { - return; - } - if (args.kind === 'url-token') { - return { - path: args.path, - external: true, - }; - } - for (const [key] of Object.entries(compiler.config.globals)) { - const isMatch = pm(key); - if (isMatch(args.path)) { - return { - path: args.path, - namespace: LibuildGlobalNamespace, - }; - } - } - /** - * The node: protocol was added to require in Node v14.18.0 - * https://nodejs.org/api/esm.html#node-imports - */ - if (/^node:/.test(args.path)) { - return { - path: args.path.slice(5), - external: true, - }; - } - const result = await compiler.hooks.resolve.promise(args); - - if ( - result?.path && - !path.isAbsolute(result.path) && - !result.external && - !DATAURL_JAVASCRIPT_PATTERNS.test(result.path) - ) { - return { - path: result.path, - namespace: VirtualPathProxyNamespace, - }; - } - // esbuild cant handle return non absolute path from plugin, so we need to do a trick to handle this - // see https://github.com/evanw/esbuild/issues/2404 - if (DATAURL_JAVASCRIPT_PATTERNS.test(args.path)) { - return { - path: args.path, - namespace: 'dataurl', - }; - } - - if (result != null) { - return result; - } - }); - build.onLoad({ filter: /.*/ }, async args => { - compiler.config.logger.debug('onLoad', args.path); - - if (args.namespace === LibuildGlobalNamespace) { - const value = compiler.config.globals[args.path]; - return { - contents: `module.exports = (typeof globalThis !== "undefined" ? globalThis : Function('return this')() || global || self)[${JSON.stringify( - value, - )}]`, - }; - } - if (args.suffix) { - args.path += args.suffix; - } - if ( - args.namespace !== 'file' && - args.namespace !== VirtualPathProxyNamespace && - args.namespace !== LibuildVirtualNamespace - ) { - return; - } - - let result = await compiler.hooks.load.promise(args); - if (result == null) { - // let esbuild to handle data:text/javascript - if (DATAURL_JAVASCRIPT_PATTERNS.test(args.path)) { - return; - } - result = { - contents: await internalLoad(args.path), - }; - } - - // file don't need transform when loader is copy - if (!result.contents || result.loader === 'copy') { - return result; - } - - const { originalFilePath } = resolvePathAndQuery(args.path); - - if (originalFilePath) { - compiler.addWatchFile(originalFilePath); - } - - const context = compiler.getTransformContext(args.path); - - context.addSourceMap(context.genPluginId('adapter'), result.map); - - const transformResult = await compiler.hooks.transform.promise({ - code: result.contents.toString(), - path: args.path, - loader: result.loader, - }); - const ext = path.extname(args.path); - const loader = (transformResult.loader ?? - compiler.config.loader[ext] ?? - loaderMap[ext]) as Loader; - const inlineSourceMap = context.getInlineSourceMap(); - - return { - contents: transformResult.code + inlineSourceMap, - loader, - resolveDir: - result.resolveDir ?? - (args.namespace === VirtualPathProxyNamespace - ? compiler.config.root - : path.dirname(args.path)), - }; - }); - build.onEnd(async result => { - compiler.config.logger.debug('onEnd'); - if (result.errors.length) { - return; - } - - addCssEntryPoint(result); - - const entryPoints = Object.values( - build.initialOptions.entryPoints!, - ).map(i => normalizeEntryPoint(i, compiler.config.root)); - - await normalizeOutput(compiler, result, entryPoints); - - for (const [key, value] of compiler.outputChunk.entries()) { - const context = compiler.getSourcemapContext(value.fileName); - if (value.type === 'chunk' && compiler.config.sourceMap) { - context.addSourceMap(context.genPluginId('adapter'), value.map); - } - const processedResult = await compiler.hooks.processAsset.promise( - value, - ); - if (processedResult.type === 'chunk' && compiler.config.sourceMap) { - processedResult.map = context.getSourceMap(); - } - compiler.outputChunk.set(key, processedResult); - } - - const manifest = { - type: 'esbuild' as const, - metafile: result.metafile!, - config: build.initialOptions, - }; - - await compiler.hooks.processAssets.promise( - compiler.outputChunk, - manifest, - ); - await compiler.hooks.endCompilation.promise(compiler.getErrors()); - }); - }, - }; -}; - -export function findEntry(paths: string[], otherPaths: string) { - paths = paths.sort((a, b) => a.length - b.length); - let max = 0; - let value = null; - for (const path of paths) { - for (let i = 0; i < Math.min(path.length, otherPaths.length); i++) { - if (path.charAt(i) !== otherPaths.charAt(i)) { - if (i > max) { - max = i; - value = path; - } - break; - } - } - } - return value; -} - -async function normalizeOutput( - compiler: ILibuilder, - result: BuildResult, - entryPoints: string[], -) { - const { outputs } = result.metafile!; - const { root } = compiler.config; - const needSourceMap = Boolean(compiler.config.sourceMap); - const entries: Record = {}; - for (const [key, value] of Object.entries(outputs)) { - if (key.endsWith('.map')) { - continue; - } - const absPath = path.resolve(root, key); - const item = result.outputFiles?.find(x => x.path === absPath); - const mapping = result.outputFiles?.find( - x => x.path.endsWith('.map') && x.path.replace(/\.map$/, '') === absPath, - ); - if (!item) { - throw new Error(`no contents for ${absPath}`); - } - let { entryPoint } = value; - if (absPath.endsWith('.js')) { - const isEntry = isEntryPoint(entryPoints, root, entryPoint); - compiler.emitAsset(absPath, { - type: 'chunk', - contents: item.text, - map: normalizeSourceMap(mapping?.text, { needSourceMap }), - entryPoint: entryPoint - ? normalizeEntryPoint(entryPoint, root) - : undefined, - fileName: absPath, - isEntry, - }); - if (isEntry) { - entryPoint = normalizeEntryPoint(entryPoint!, root); - entries[entryPoint] = { - name: normalizeEntryName(entryPoint, compiler.config.input), - path: entryPoint, - chunkNames: [absPath], - }; - } - } else { - compiler.emitAsset(absPath, { - type: 'asset', - contents: Buffer.from(item.contents), - entryPoint: entryPoint - ? normalizeEntryPoint(entryPoint, root) - : undefined, - fileName: absPath, - }); - } - } -} - -function normalizeEntryPoint(entryPoint: string, root: string) { - if (entryPoint.startsWith(root)) { - return entryPoint; - } - if (entryPoint.startsWith(LibuildVirtualNamespace)) { - const value = entryPoint.replace(`${LibuildVirtualNamespace}:`, ''); - if (value.startsWith(root)) { - return value; - } - return path.join(root, value); - } - if (fs.existsSync(path.join(root, entryPoint))) { - return path.join(root, entryPoint); - } - return path.join(root, entryPoint); -} - -function isEntryPoint( - entryPoints: string[], - root: string, - entryPoint?: string, -): boolean { - return Boolean( - entryPoint && entryPoints.includes(normalizeEntryPoint(entryPoint, root)), - ); -} - -// fix css has no entryPoints -function addCssEntryPoint(result: BuildResult) { - const { outputs } = result.metafile!; - const outputJsPaths = Object.keys(outputs).filter(x => x.endsWith('.js')); - for (const [key, value] of Object.entries(outputs)) { - if (key.endsWith('.css') && !value.entryPoint) { - const jsPath = findEntry(outputJsPaths, key); - const item = outputs[jsPath!]; - value.entryPoint = item.entryPoint; - } - } -} - -function normalizeEntryName( - entryPath: string, - inputs: BuildConfig['input'], -): string { - const { query } = resolvePathAndQuery(entryPath); - for (const [entryName, entry] of Object.entries(inputs)) { - if (typeof entry === 'string' && entry === entryPath) { - return entryName; - } - } - return query.name as string; -} diff --git a/packages/libuild/libuild-core/src/bundler/index.ts b/packages/libuild/libuild-core/src/bundler/index.ts deleted file mode 100644 index 26f6cc779003..000000000000 --- a/packages/libuild/libuild-core/src/bundler/index.ts +++ /dev/null @@ -1,320 +0,0 @@ -import { - LogLevel as esbuildLogLevel, - BuildResult, - BuildOptions, - BuildContext, - context, - build, -} from 'esbuild'; -import chalk from 'chalk'; -import { getLogLevel } from '../logger'; -import { LibuildError } from '../error'; -import { - Callback, - ILibuilder, - BuildConfig, - IBuilderBase, - EsbuildResultInfo, - EsbuildError, -} from '../types'; -import { jsExtensions } from '../core/resolve'; -import { ErrorCode } from '../constants/error'; -import type { Format } from '../types/config'; -import { - swcTransformPluginName, - es5PluginName, - umdPluginName, -} from '../constants/plugins'; -import { adapterPlugin } from './adapter'; - -function convertLogLevel(level: BuildConfig['logLevel']): esbuildLogLevel { - if (getLogLevel(level) < getLogLevel('debug')) { - return 'silent'; - } - return level; -} - -function getEsbuildTarget(options: { - enableSwcTransform: boolean; - haveUmdPlugin: boolean; - haveEs5Plugin: boolean; - target: string; - format: Format; -}) { - const { enableSwcTransform, haveUmdPlugin, haveEs5Plugin, target, format } = - options; - if (format === 'umd' && haveUmdPlugin) { - // umd-plugin will transform syntax by user-target. - return undefined; - } - - if (enableSwcTransform) { - // swc-transform will transform syntax by user-target - // when esbuild target is undefined. esbuild will transform nothing about syntax. - - // but es5 is special, must be set to 'es5'. - // eg: when esbuild target is not 'es5'. swc-transform result is {value: value}, esbuild will transform it to {value} - if (target === 'es5') { - return 'es5'; - } - - return undefined; - } - - // default case, use esbuild-transform target or es5-plugin. - return haveEs5Plugin ? 'esnext' : target; -} - -function getEsbuildFormat(options: { - enableSwcTransform: boolean; - bundle: boolean; - format?: Format; - splitting: boolean; -}) { - const { enableSwcTransform, format, bundle, splitting } = options; - - // cjs splitting - // with ./plugins/format-cjs - if (bundle && splitting && format === 'cjs') { - return 'esm'; - } - - if (format === 'esm' || format === 'cjs') { - // swc transform and bundleless build - if (enableSwcTransform && !bundle) { - return undefined; - } - - // case1: default transform - // case2: swc transform and bundle build - return format; - } - - // when format is umd, disable swc-transform and use umd-plugin, - // so esbuild format should be `esm`. - if (format === 'umd') { - // https://esbuild.github.io/api/#format - // When no output format is specified, esbuild picks an output format for you if bundling is enabled (as described below), - // or **doesn't do any format conversion if bundling is disabled**. - return bundle ? 'esm' : undefined; - } - - // when format is iife, swc-transform only transform syntax, esbuild transform js format. - if (format === 'iife') { - return 'iife'; - } - - // fallback - return format; -} - -export class EsbuildBuilder implements IBuilderBase { - compiler: ILibuilder; - - instance?: BuildContext; - - result?: BuildResult; - - reBuildCount: number; - - constructor(compiler: ILibuilder) { - this.compiler = compiler; - this.reBuildCount = 0; - } - - close(callback?: Callback) { - try { - this.instance?.cancel(); - this.instance?.dispose(); - callback?.(); - /* c8 ignore next */ - } catch (err) { - /* c8 ignore next */ - callback?.(err); - } - } - - private async report(error: EsbuildResultInfo) { - const { compiler } = this; - compiler.report(this.parseError(error)); - await compiler.hooks.endCompilation.promise(compiler.getErrors()); - } - - private parseError(err: EsbuildResultInfo) { - const infos: LibuildError[] = []; - const parseDetail = (item: EsbuildError) => { - if (item.detail) { - return this.parseError(item.detail); - } - }; - - if (err.errors) { - infos.push( - ...err.errors - .map((item: EsbuildError) => { - return ( - parseDetail(item) ?? - LibuildError.from(item, { - level: 'Error', - code: ErrorCode.ESBUILD_ERROR, - }) - ); - }) - .reduce((acc: any[], val: any) => acc.concat(val), []), - ); - } - - if (err.warnings) { - infos.push( - ...err.warnings - .map((item: EsbuildError) => { - return ( - parseDetail(item) ?? - LibuildError.from(item, { - level: 'Warn', - code: ErrorCode.ESBUILD_WARN, - }) - ); - }) - .reduce((acc: any[], val: any) => acc.concat(val), []), - ); - } - - if (infos.length === 0) { - infos.push(LibuildError.from(err)); - } - - return infos; - } - - async build() { - // /** - // * it's pity that esbuild doesn't supports inline tsconfig - // * fix me later after https://github.com/evanw/esbuild/issues/943 resolved - // */ - // const tsConfigPath = path.resolve(__dirname, '../config/tsconfig.json'); - // if (!fs.existsSync(tsConfigPath)) { - // throw new Error(`failed to load tsconfig at ${tsConfigPath}`); - // } - - const { compiler } = this; - const { - input, - bundle, - define, - target, - sourceMap, - resolve, - watch, - platform, - logLevel, - inject, - root, - splitting, - outdir, - outbase, - entryNames, - minify, - chunkNames, - jsx, - esbuildOptions, - format, - asset, - } = compiler.config; - - // if have libuild:swc-transform, so enable swc-transform - const enableSwcTransform = Boolean( - compiler.plugins.find(plugin => plugin.name === swcTransformPluginName), - ); - const haveUmdPlugin = Boolean( - compiler.plugins.find(plugin => plugin.name === umdPluginName), - ); - const haveEs5Plugin = Boolean( - compiler.plugins.find(plugin => plugin.name === es5PluginName), - ); - - const esbuildFormat = getEsbuildFormat({ - enableSwcTransform, - bundle, - format, - splitting, - }); - const esbuildTarget = getEsbuildTarget({ - enableSwcTransform, - haveUmdPlugin, - haveEs5Plugin, - format, - target, - }); - - const esbuildConfig: BuildOptions = { - entryPoints: input, - metafile: true, - define, - bundle, - format: esbuildFormat, - target: esbuildTarget, - sourcemap: sourceMap ? 'external' : false, - mainFields: resolve.mainFields, - resolveExtensions: jsExtensions, - splitting, - charset: 'utf8', - logLimit: 5, - absWorkingDir: root, - platform, - write: false, - logLevel: convertLogLevel(logLevel), - outdir, - outbase, - entryNames, - chunkNames, - plugins: [adapterPlugin(this.compiler)], - minifyIdentifiers: Boolean(minify), - minify: minify === 'esbuild', - inject, - jsx, - supported: { - 'dynamic-import': bundle || format !== 'cjs', - }, - assetNames: `${asset.outdir}/[name].[hash]`, - }; - - const buildOptions = esbuildOptions(esbuildConfig); - try { - if (watch) { - this.instance = await context(buildOptions); - this.result = await this.instance.rebuild(); - } else { - this.result = await build(buildOptions); - } - if (this.result.warnings.length) { - this.report(this.result); - } - } catch (error: any) { - await this.report(error); - - if (watch) { - this.instance?.cancel(); - } - } - } - - async reBuild(type: 'link' | 'change') { - const { instance, compiler } = this; - try { - const start = Date.now(); - if (type === 'link') { - await this.build(); - } else { - this.result = await instance?.rebuild(); - } - compiler.config.logger.info( - chalk.green`Rebuild Successfully in ${Date.now() - start}ms`, - chalk.yellow`Rebuild Count: ${++this.reBuildCount}`, - ); - } catch (error: any) { - this.report(error); - compiler.printErrors(); - } - } -} diff --git a/packages/libuild/libuild-core/src/bundler/resolve.ts b/packages/libuild/libuild-core/src/bundler/resolve.ts deleted file mode 100644 index 066093db330f..000000000000 --- a/packages/libuild/libuild-core/src/bundler/resolve.ts +++ /dev/null @@ -1,153 +0,0 @@ -import path from 'path'; -import fs from 'fs'; -import module from 'module'; -import { resolvePathAndQuery } from '@modern-js/libuild-utils'; -import { createFilter } from '@rollup/pluginutils'; -import type { BuilderResolveOptions, ILibuilder, SideEffects } from '../types'; - -const HTTP_PATTERNS = /^(https?:)?\/\//; -const DATAURL_PATTERNS = /^data:/; -const HASH_PATTERNS = /#[^#]+$/; -export const isUrl = (source: string) => - HTTP_PATTERNS.test(source) || - DATAURL_PATTERNS.test(source) || - HASH_PATTERNS.test(source); - -function isString(str: unknown): str is string { - return typeof str === 'string'; -} - -export function installResolve(compiler: ILibuilder): ILibuilder['resolve'] { - const { external, sideEffects: userSideEffects } = compiler.config; - const regExternal = external.filter( - (item): item is RegExp => !isString(item), - ); - const externalList = external - .filter(isString) - .concat(Object.keys(compiler.config.globals)) - .concat(compiler.config.platform === 'node' ? module.builtinModules : []); - - const externalMap = externalList.reduce((map, item) => { - map.set(item, true); - return map; - }, new Map()); - - function getResolverDir(importer?: string, resolveDir?: string) { - return ( - resolveDir ?? (importer ? path.dirname(importer) : compiler.config.root) - ); - } - - function getResolveResult(source: string, opt: BuilderResolveOptions) { - if (source.endsWith('.css')) { - return compiler.config.css_resolve( - source, - getResolverDir(opt.importer, opt.resolveDir), - ); - } - - return compiler.config.node_resolve( - source, - getResolverDir(opt.importer, opt.resolveDir), - opt.kind, - ); - } - - function getIsExternal(name: string) { - if (externalMap.get(name)) { - return true; - } - - if (regExternal.some(reg => reg.test(name))) { - return true; - } - - return false; - } - - /** - * return module sideEffects - * @todo fix subpath later - * @param filePath - * @param isExternal - * @returns - */ - async function getSideEffects( - filePath: string | boolean, - isExternal: boolean, - ) { - if (typeof filePath === 'boolean') { - return false; - } - let moduleSideEffects = true; - let sideEffects: SideEffects | undefined | string[] = userSideEffects; - let pkgPath = ''; - if (typeof userSideEffects === 'undefined') { - let curDir = path.dirname(filePath); - try { - while (curDir !== path.dirname(curDir)) { - if (fs.existsSync(path.resolve(curDir, 'package.json'))) { - pkgPath = path.resolve(curDir, 'package.json'); - break; - } - curDir = path.dirname(curDir); - } - sideEffects = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')).sideEffects; - } catch (err) { - // just ignore in case some system permission exception happens - } - if (!pkgPath) { - return undefined; - } - } - if (typeof sideEffects === 'boolean') { - moduleSideEffects = sideEffects; - } else if (Array.isArray(sideEffects)) { - moduleSideEffects = createFilter( - sideEffects.map(glob => { - if (typeof glob === 'string') { - if (!glob.includes('/')) { - return `**/${glob}`; - } - } - return glob; - }), - null, - pkgPath - ? { - resolve: path.dirname(pkgPath), - } - : undefined, - )(filePath); - } else if (typeof sideEffects === 'function') { - moduleSideEffects = sideEffects(filePath, isExternal); - } - return moduleSideEffects; - } - - return async (source, options = {}) => { - if (isUrl(source)) { - return { - path: source, - external: true, - }; - } - - const { originalFilePath, rawQuery } = resolvePathAndQuery(source); - const suffix = (rawQuery ?? '').length > 0 ? `?${rawQuery}` : ''; - const isExternal = getIsExternal(originalFilePath); - const resultPath = isExternal - ? originalFilePath - : getResolveResult(originalFilePath, options); - - return { - external: isExternal, - namespace: isExternal ? undefined : 'file', - sideEffects: options.skipSideEffects - ? false - : await getSideEffects(resultPath, isExternal), - path: resultPath, - suffix, - }; - }; -} diff --git a/packages/libuild/libuild-core/src/constants/config.ts b/packages/libuild/libuild-core/src/constants/config.ts deleted file mode 100644 index d52091e7cb9c..000000000000 --- a/packages/libuild/libuild-core/src/constants/config.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const WEBSITE_URL = 'https://modernjs.dev/'; -export const DEFAULT_NODE_ENV = 'production'; -export const DEFAULT_OUTDIR = 'dist'; -export const DEFAULT_OUTBASE = 'src'; diff --git a/packages/libuild/libuild-core/src/constants/error.ts b/packages/libuild/libuild-core/src/constants/error.ts deleted file mode 100644 index 83dc2dd73da5..000000000000 --- a/packages/libuild/libuild-core/src/constants/error.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const enum ErrorCode { - CONFIG_NOT_EXIT = 'CONFIG_NOT_EXIT', - NODE_RESOLVE_FAILED = 'NODE_RESOLVE_FAILED', - ESBUILD_ERROR = 'ESBUILD_ERROR', - ESBUILD_WARN = 'ESBUILD_WARN', - RESOLVE_OUT_OF_PLUGIN = 'RESOLVE_OUT_OF_PLUGIN', - PLUGIN_INTERNAL_ERROR = 'PLUGIN_INTERNAL_ERROR', -} diff --git a/packages/libuild/libuild-core/src/constants/plugins.ts b/packages/libuild/libuild-core/src/constants/plugins.ts deleted file mode 100644 index 86d21cb21ed9..000000000000 --- a/packages/libuild/libuild-core/src/constants/plugins.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const swcTransformPluginName = 'libuild:swc-transform'; -export const umdPluginName = 'libuild:swc-umd'; -export const es5PluginName = 'libuild:swc-es5'; diff --git a/packages/libuild/libuild-core/src/constants/regExp.ts b/packages/libuild/libuild-core/src/constants/regExp.ts deleted file mode 100644 index 696f75d9e326..000000000000 --- a/packages/libuild/libuild-core/src/constants/regExp.ts +++ /dev/null @@ -1 +0,0 @@ -export const DATAURL_JAVASCRIPT_PATTERNS = /^data:text\/javascript/; diff --git a/packages/libuild/libuild-core/src/core/index.ts b/packages/libuild/libuild-core/src/core/index.ts deleted file mode 100644 index 9b910c2aec71..000000000000 --- a/packages/libuild/libuild-core/src/core/index.ts +++ /dev/null @@ -1,262 +0,0 @@ -import * as tapable from 'tapable'; -import { FSWatcher } from 'chokidar'; - -import { LibuildError, warpErrors, LibuildFailure } from '../error'; -import { - CLIConfig, - BuildConfig, - ILibuilder, - LibuildPlugin, - ResolveArgs, - LoadArgs, - ResolveResult, - LoadResult, - Chunk, - LibuildManifest, - Callback, - BuilderResolveResult, - BuilderResolveOptions, - ILibuilderStage, - ILibuilderHooks, - IBuilderBase, - LibuildErrorParams, - LibuildErrorInstance, -} from '../types'; -import { normalizeConfig } from '../utils/normalizeConfig'; -import { getInternalPlugin } from '../plugins/getInternalPlugin'; -import { ErrorCode } from '../constants/error'; -import { EsbuildBuilder } from '../bundler'; -import { createTransformHook, createProcessAssetHook } from './utils'; -import { TransformContext } from './transform'; -import { SourcemapContext } from './sourcemap'; - -export class Libuilder implements ILibuilder { - static async run( - config: CLIConfig = {}, - name?: string, - ): Promise { - const compiler = await Libuilder.create(config, name); - await compiler.build(); - return compiler; - } - - static async create( - config: CLIConfig = {}, - name?: string, - ): Promise { - const builder = new Libuilder(); - - builder.name = name; - builder.version = require('../../package.json').version; - - try { - await builder.init(config); - await builder.hooks.initialize.promise(); - } catch (e: unknown) { - builder.report(e); - throw builder.getErrors(); - } - - return builder; - } - - compilation!: IBuilderBase; - - version!: string; - - watchedFiles: Set = new Set(); - - // @ts-expect-error - hooks: ILibuilderHooks; - - STAGE: ILibuilderStage = { - /** - * Execute Before Internal Plugin - */ - PRE_INTERNAL: -255, - /** - * Execute After Internal Plugin - */ - POST_INTERNAL: 255, - }; - - userConfig!: CLIConfig; - - config!: BuildConfig; - - plugins: LibuildPlugin[] = []; - - outputChunk: Map = new Map(); - - virtualModule: Map = new Map(); - - name?: string; - - private errors: LibuildError[] = []; - - private watcher?: FSWatcher; - - private transformContextMap: Map = new Map(); - - private sourcemapContextMap: Map = new Map(); - - async init(config: CLIConfig) { - this.userConfig = config; - this.config = await normalizeConfig(config); - this.hooks = Object.freeze({ - initialize: new tapable.AsyncSeriesHook<[], void>(), - startCompilation: new tapable.AsyncSeriesHook<[]>([]), - resolve: new tapable.AsyncSeriesBailHook< - [ResolveArgs], - ResolveResult | undefined - >(['resolveArgs']), - load: new tapable.AsyncSeriesBailHook< - [LoadArgs], - LoadResult | undefined | void - >(['loadArgs']), - transform: createTransformHook(this), - processAsset: createProcessAssetHook(this), - processAssets: new tapable.AsyncSeriesHook< - [Map, LibuildManifest] - >(['chunks', 'manifest']), - endCompilation: new tapable.AsyncSeriesHook<[LibuildFailure]>(['errors']), - watchChange: new tapable.SyncHook<[string[]]>(['id']), - done: new tapable.AsyncSeriesHook<[]>([]), - shutdown: new tapable.AsyncSeriesHook<[]>(), - }); - // load plugins - const userPlugin = this.config.plugins; - const internalPlugin = await getInternalPlugin(this.config); - this.plugins = [...userPlugin, ...internalPlugin]; - for (const plugin of this.plugins) { - plugin.apply(this); - } - } - - async build() { - this.compilation = new EsbuildBuilder(this); - await this.compilation.build(); - const result = this.getErrors(); - - /** - * first build end - * - in watch mode, only print error - * - in normal mode - * - has error, will throw to outside, - * - otherwise print error - */ - if (result.errors.length > 0 && !this.config.watch) { - throw result; - } else { - this.printErrors(); - } - } - - async close(callback?: Callback) { - await this.hooks.shutdown.promise(); - this.compilation?.close(callback); - } - - emitAsset(name: string, chunk: string | Chunk) { - if (typeof chunk === 'string') { - this.outputChunk.set(name, { - type: 'asset', - contents: chunk, - fileName: name, - }); - } else { - this.outputChunk.set(name, chunk); - } - } - - addWatchFile(id: string): void { - if (!this.watchedFiles.has(id)) { - this.watcher?.add?.(id); - this.watchedFiles.add(id); - } - } - - resolve( - _source: string, - _opt?: BuilderResolveOptions, - ): Promise { - throw new LibuildError( - ErrorCode.RESOLVE_OUT_OF_PLUGIN, - 'resolve is not allowed to called out of plugin', - ); - } - - async loadSvgr(_path: string) {} - - getTransformContext(path: string): TransformContext { - if (this.transformContextMap.has(path)) { - return this.transformContextMap.get(path)!; - } - const context: TransformContext = new TransformContext( - true, - Boolean(this.config.sourceMap), - ); - this.transformContextMap.set(path, context); - return context; - } - - getSourcemapContext(path: string): SourcemapContext { - if (this.sourcemapContextMap.has(path)) { - return this.sourcemapContextMap.get(path)!; - } - const context: SourcemapContext = new SourcemapContext( - Boolean(this.config.sourceMap), - ); - this.sourcemapContextMap.set(path, context); - return context; - } - - report(err: any) { - if (Array.isArray(err)) { - this.errors.push(...err.map(item => LibuildError.from(item))); - } else { - this.errors.push(LibuildError.from(err)); - } - } - - throw(message: string, opts?: LibuildErrorParams) { - throw new LibuildError(ErrorCode.PLUGIN_INTERNAL_ERROR, message, opts); - } - - printErrors() { - if (this.config.logLevel === 'silent') { - return; - } - - const data = this.getErrors(); - const formatted = data.toString(); - - if (formatted.length > 0) { - if (data.errors.length === 0) { - this.config.logger.warn(formatted); - } else { - this.config.logger.error(formatted); - } - } - } - - getErrors(): LibuildFailure { - const data = this.errors.slice(); - - return warpErrors(data, this.config?.logLevel); - } - - clearErrors() { - this.errors.length = 0; - } - - removeError(...errors: LibuildErrorInstance[]): void { - for (const err of errors) { - const index = this.errors.findIndex(item => item === err); - - if (index > -1) { - this.errors.splice(index, 1); - } - } - } -} diff --git a/packages/libuild/libuild-core/src/core/resolve.ts b/packages/libuild/libuild-core/src/core/resolve.ts deleted file mode 100644 index c8d1a453f321..000000000000 --- a/packages/libuild/libuild-core/src/core/resolve.ts +++ /dev/null @@ -1,115 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import { CachedInputFileSystem, create } from 'enhanced-resolve'; -import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; -import { ImportKind } from 'esbuild'; -import { LibuildError } from '../error'; -import { UserConfig } from '../types'; -import { ErrorCode } from '../constants/error'; - -export const jsExtensions = ['.jsx', '.tsx', '.js', '.ts', '.json']; -/** - * supports require js plugin in less file - */ -export const cssExtensions = ['.less', '.css', '.sass', '.scss', '.js']; - -function createEnhancedResolve(options: ResolverOptions): { - resolveSync: { - resolve: (dir: string, id: string) => string /** TODO: string | false */; - }; - esmResolveSync: { - resolve: (dir: string, id: string) => string /** TODO: string | false */; - }; -} { - const plugins = []; - const tsconfigPath = path.join(options.root, './tsconfig.json'); - // tsconfig-paths directly statSync `tsconfig.json` without confirm it's exist. - if (fs.existsSync(tsconfigPath)) { - plugins.push( - new TsconfigPathsPlugin({ - baseUrl: options.root, - configFile: tsconfigPath, - }), - ); - } - const resolveOptions = { - aliasFields: options.platform === 'browser' ? ['browser'] : [], - FileSystem: new CachedInputFileSystem(fs, 4000), - mainFields: options.mainFields ?? ['module', 'browser', 'main'], - mainFiles: options.mainFiles, - extensions: options.extensions, - preferRelative: options.preferRelative, - addMatchAll: false, - plugins, - alias: options.alias, - }; - // conditionNames follow webpack options - // cjs - const resolveSync = { - resolve: (dir: string, id: string) => - create.sync({ - ...resolveOptions, - conditionNames: [options.platform, 'require', 'module'], - })(dir, id), - }; - const esmResolveSync = { - resolve: (dir: string, id: string) => - create.sync({ - ...resolveOptions, - conditionNames: [options.platform, 'import', 'module'], - })(dir, id), - }; - return { - // @ts-expect-error - resolveSync, - // @ts-expect-error - esmResolveSync, - }; -} - -interface ResolverOptions { - platform: NonNullable; - resolveType: 'css' | 'js'; - root: string; - mainFields?: string[]; - mainFiles?: string[]; - alias?: Record; - preferRelative?: boolean; - extensions?: string[]; - enableNativeResolve?: boolean; -} - -export const createResolver = (options: ResolverOptions) => { - const resolveCache = new Map(); - const { resolveSync, esmResolveSync } = createEnhancedResolve(options); - const resolver = (id: string, dir: string, kind?: ImportKind) => { - // eslint-disable-next-line @typescript-eslint/restrict-plus-operands - const cacheKey = id + dir + kind; - const cacheResult = resolveCache.get(cacheKey); - - if (cacheResult) { - return cacheResult; - } - let result: string; - try { - if (options.resolveType === 'js') { - if (kind === 'import-statement' || kind === 'dynamic-import') { - result = esmResolveSync.resolve(dir, id); - } else { - result = resolveSync.resolve(dir, id); - } - } else { - try { - result = resolveSync.resolve(dir, id); - } catch (err) { - result = resolveSync.resolve(dir, id.replace(/^~/, '')); - } - } - resolveCache.set(cacheKey, result); - return result; - } catch (err: any) { - throw new LibuildError(ErrorCode.NODE_RESOLVE_FAILED, err.message); - } - }; - return resolver; -}; diff --git a/packages/libuild/libuild-core/src/core/transform.ts b/packages/libuild/libuild-core/src/core/transform.ts deleted file mode 100644 index a0c1fc655864..000000000000 --- a/packages/libuild/libuild-core/src/core/transform.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ITransformContext, CacheValue } from '../types'; -import { SourcemapContext } from './sourcemap'; - -export class TransformContext - extends SourcemapContext - implements ITransformContext -{ - private cachedTransformResult: Map = new Map< - number, - CacheValue - >(); - - constructor(private enableCache?: boolean, enableSourceMap?: boolean) { - super(enableSourceMap); - } - - public addTransformResult(pluginId: number, result: CacheValue) { - if (result.cache !== false && this.enableCache) { - this.cachedTransformResult.set(pluginId, result); - } - this.addSourceMap(pluginId, result.map); - } - - public getValidCache(pluginId: number, code: string) { - if (this.enableCache) { - const cache = this.cachedTransformResult.get(pluginId); - if (cache && cache.originCode === code) { - return cache; - } - } - } -} diff --git a/packages/libuild/libuild-core/src/error/error.ts b/packages/libuild/libuild-core/src/error/error.ts deleted file mode 100644 index ab25a9e9ebaf..000000000000 --- a/packages/libuild/libuild-core/src/error/error.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { Instance, Chalk } from 'chalk'; -import { codeFrameColumns } from '@babel/code-frame'; -import deepEql from 'deep-eql'; -import { isDef } from '@modern-js/libuild-utils'; -import { - LibuildErrorInstance, - LibuildErrorParams, - CodeFrameOption, - ControllerOption, - ErrorLevel, -} from '../types'; -import { transform, toLevel, insertSpace } from './utils'; - -export class LibuildError extends Error implements LibuildErrorInstance { - static from(err: unknown, opt?: LibuildErrorParams): LibuildError { - if (err instanceof LibuildError) { - return err; - } - - return transform(err, opt); - } - - readonly prefixCode: string; - - readonly code: string; - - readonly reason?: string; - - readonly hint?: string; - - readonly referenceUrl?: string; - - private codeFrame?: CodeFrameOption; - - private _controller: ControllerOption = { - noStack: true, - noColor: false, - }; - - private readonly _level: ErrorLevel; - - constructor(code: string, message: string, opts?: LibuildErrorParams) { - super(message); - this.code = code; - this.hint = opts?.hint; - this.reason = opts?.reason; - this.stack = opts?.stack; - this._level = opts?.level ? toLevel(opts.level) : ErrorLevel.Error; - this.referenceUrl = opts?.referenceUrl; - this.codeFrame = opts?.codeFrame; - this.prefixCode = opts?.prefixCode ?? 'Libuild'; - - this.setControllerOption(opts?.controller ?? {}); - } - - get level() { - return ErrorLevel[this._level] as keyof typeof ErrorLevel; - } - - get path() { - return this.codeFrame?.filePath; - } - - set path(file: string | undefined) { - if (!file) { - return; - } - - if (this.codeFrame) { - this.codeFrame.filePath = file; - return; - } - - this.codeFrame = { - filePath: file, - }; - } - - private printCodeFrame(print: Chalk) { - const msgs: string[] = []; - const { codeFrame: codeFrameOpt, _controller: controller } = this; - - if (!codeFrameOpt) { - return msgs; - } - - // There are starting positions and specific codes need to be printed - if ('start' in codeFrameOpt && codeFrameOpt.start) { - const { filePath, start } = codeFrameOpt; - - // Print file path and starting point coordinates - msgs.push( - `\n ${print.red(print.bold('File: '))}${print.bold(filePath)}:${ - start.line - }${start.column ? `:${start.column}` : ''}`, - ); - - if ('fileContent' in codeFrameOpt) { - const { end, fileContent } = codeFrameOpt; - - msgs.push( - codeFrameColumns( - fileContent, - { - start, - end, - }, - { - highlightCode: !controller.noColor, - }, - ), - ); - } else { - const { length, lineText } = codeFrameOpt; - let lineCodeFrame = codeFrameColumns( - lineText, - { - start: { - line: 1, - column: start.column, - }, - end: { - line: 1, - column: - isDef(start.column) && isDef(length) - ? start.column + length - : undefined, - }, - }, - { - highlightCode: !controller.noColor, - }, - ); - - if (start.line > 1) { - lineCodeFrame = lineCodeFrame.replace(' 1 |', ` ${start.line} |`); - - if (start.line >= 10) { - lineCodeFrame = insertSpace( - lineCodeFrame, - 2, - String(start.line).length - 1, - ); - } - } - - msgs.push(lineCodeFrame); - } - } - // If the starting location does not exist, only the file path is printed - else { - msgs.push( - `\n ${print.red(print.bold('File: '))}${print.bold( - codeFrameOpt.filePath, - )}\n`, - ); - } - - return msgs; - } - - toString() { - const msgs: string[] = []; - const { - code, - reason, - prefixCode, - message, - hint, - referenceUrl, - _controller: controller, - } = this; - const print = controller.noColor - ? new Instance({ level: 0 }) - : new Instance({ level: 3 }); - const mainColorPrint = - this._level === ErrorLevel.Error ? print.red : print.yellow; - const reasonCode = reason ? `${mainColorPrint.blue(reason)}: ` : ''; - - msgs.push( - mainColorPrint.bold( - `[${prefixCode.toUpperCase()}:${code.toUpperCase()}] `, - ) + - reasonCode + - message, - ); - msgs.push(...this.printCodeFrame(print)); - - if (hint) { - msgs.push(`\n ${print.blue(`HINT: ${hint}`)}`); - } - - if (referenceUrl) { - msgs.push(print.magenta.bold(` See: ${referenceUrl}`)); - } - - if (!controller.noStack && this.stack) { - msgs.push(print.red.bold(` Error Stack:\n${this.stack}\n`)); - } - - return msgs.join('\n'); - } - - setControllerOption(opt: ControllerOption) { - this._controller = { - noStack: opt.noStack ?? this._controller.noStack ?? true, - noColor: opt.noColor ?? this._controller.noColor ?? false, - }; - } - - setCodeFrame(opt: CodeFrameOption) { - this.codeFrame = opt; - } - - isSame(error: LibuildError) { - const basicSame = - this.code === error.code && - this.message === error.message && - this.hint === error.hint && - this._level === error._level && - this.referenceUrl === error.referenceUrl && - this.prefixCode === error.prefixCode && - deepEql(this.codeFrame, error.codeFrame); - - return basicSame; - } -} diff --git a/packages/libuild/libuild-core/src/error/failure.ts b/packages/libuild/libuild-core/src/error/failure.ts deleted file mode 100644 index 7b9ff27428e2..000000000000 --- a/packages/libuild/libuild-core/src/error/failure.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { LibuildErrorInstance } from '../types'; - -export class LibuildFailure extends Error { - readonly errors: LibuildErrorInstance[]; - - readonly warnings: LibuildErrorInstance[]; - - readonly logLevel: string; - - constructor( - errors: LibuildErrorInstance[], - warnings: LibuildErrorInstance[], - logLevel: string, - ) { - super(); - this.errors = errors; - this.warnings = warnings; - this.logLevel = logLevel; - } - - toString() { - const { logLevel, errors, warnings } = this; - const onlyError = logLevel === 'error'; - - if (logLevel === 'silent') { - return ''; - } - - if ( - (onlyError && errors.length === 0) || - (!onlyError && errors.length === 0 && warnings.length === 0) - ) { - return ''; - } - - const msgs: string[] = []; - - if (onlyError) { - msgs.push( - `Build failed with ${errors.length} error:`, - ...errors.map(item => item.toString()), - '', - ); - } else { - const title = - errors.length === 0 - ? `Build succuss with ${warnings.length} warning:` - : `Build failed with ${errors.length} error, ${warnings.length} warning:`; - - msgs.push( - title, - ...errors.map(item => item.toString()), - ...warnings.map(item => item.toString()), - '', - ); - } - return msgs.join('\n\n'); - } -} diff --git a/packages/libuild/libuild-core/src/error/index.ts b/packages/libuild/libuild-core/src/error/index.ts deleted file mode 100644 index b6e7586954f8..000000000000 --- a/packages/libuild/libuild-core/src/error/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './error'; -export * from './utils'; -export * from './failure'; diff --git a/packages/libuild/libuild-core/src/error/utils.ts b/packages/libuild/libuild-core/src/error/utils.ts deleted file mode 100644 index 271452a7f9e6..000000000000 --- a/packages/libuild/libuild-core/src/error/utils.ts +++ /dev/null @@ -1,140 +0,0 @@ -import util from 'util'; -import chalk from 'chalk'; -import stripAnsi from 'strip-ansi'; -import { parse as stackParse } from 'stack-trace'; -import { - LibuildErrorInstance, - LogLevel, - ErrorLevel, - EsbuildError, - LibuildErrorParams, -} from '../types'; -import { ErrorCode } from '../constants/error'; -import { LibuildFailure } from './failure'; -import { LibuildError } from './error'; - -/** - * we can't use instanceof LibuildError, because it may not be an singleton class - * @param err - * @returns - */ -export function isLibuildErrorInstance(err: unknown): err is LibuildError { - return err instanceof Error && err.constructor.name === LibuildError.name; -} - -export function formatError(err: Error | LibuildErrorInstance) { - const msgs: string[] = []; - /** - * do not show stack for LibuildError by default, which is not useful for user - */ - if (isLibuildErrorInstance(err)) { - msgs.push(err.toString()); - } else if (err instanceof Error) { - if (err.stack) { - msgs.push(err.stack); - } else { - msgs.push(chalk.red(err.message)); - } - } else { - msgs.push(util.inspect(err)); - } - return msgs.join('\n'); -} - -export function toLevel(level: keyof typeof ErrorLevel) { - return ErrorLevel[level]; -} - -export function insertSpace(rawLines: string, line: number, width: number) { - const lines = rawLines.split('\n'); - lines[line - 1] = Array(width).fill(' ').join('') + lines[line - 1]; - return lines.join('\n'); -} - -export function warpErrors( - libuildErrors: LibuildError[], - logLevel: LogLevel = 'error', -): LibuildFailure { - const warnings = libuildErrors.filter(item => item.level === 'Warn'); - const errors = libuildErrors.filter(item => item.level === 'Error'); - const error = new LibuildFailure(errors, warnings, logLevel); - return error; -} - -function isEsbuildError(err: any): err is EsbuildError { - return 'pluginName' in err && 'text' in err && 'location' in err; -} - -function clearMessage(str: string) { - return stripAnsi(str).replace(/.*: (.*)\n\n[\s\S]*/g, '$1'); -} - -function clearStack(str: string) { - return str - .slice(str.indexOf(' at')) - .replace(/\s*at(.*) \((.*)\)/g, '$1\n$2\n'); -} - -function transformEsbuildError(err: any, opt?: LibuildErrorParams) { - if (isEsbuildError(err)) { - const errorCode = opt?.code ?? ErrorCode.ESBUILD_ERROR; - const libuildError = - typeof err.detail === 'object' - ? LibuildError.from(err.detail) - : new LibuildError(errorCode, clearMessage(err.text), { - ...opt, - hint: err.location?.suggestion, - codeFrame: { - filePath: err.text.split(':')[0], - }, - }); - - if (err.location) { - libuildError.setCodeFrame({ - filePath: err.location.file, - lineText: err.location.lineText, - length: err.location.length, - start: { - line: err.location.line, - column: err.location.column + 1, - }, - }); - } - - return libuildError; - } -} - -function transformNormalError(err: any, opt?: LibuildErrorParams) { - if ((err instanceof Error) as any) { - const stacks = stackParse(err); - - // err.filename is Non-standard, so filePath may be undefined yet. - const filePath = stacks[0]?.getFileName?.() || err.filename; - return new LibuildError(err.name, clearMessage(err.message), { - ...opt, - codeFrame: { - filePath, - }, - stack: err.stack && clearStack(err.stack), - }); - } -} - -function defaultError(err: any, opt?: LibuildErrorParams) { - return new LibuildError('UNKNOWN_ERROR', JSON.stringify(err), opt); -} - -export function transform(err: any, opt?: LibuildErrorParams) { - const transformers = [transformEsbuildError, transformNormalError]; - - for (const fn of transformers) { - const result = fn(err, opt); - - if (result) { - return result; - } - } - - return defaultError(err, opt); -} diff --git a/packages/libuild/libuild-core/src/index.ts b/packages/libuild/libuild-core/src/index.ts deleted file mode 100644 index 140d749bce17..000000000000 --- a/packages/libuild/libuild-core/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './core'; -export * from './types'; -export * from './error'; diff --git a/packages/libuild/libuild-core/src/logger.ts b/packages/libuild/libuild-core/src/logger.ts deleted file mode 100644 index 1ed93075f0d0..000000000000 --- a/packages/libuild/libuild-core/src/logger.ts +++ /dev/null @@ -1,76 +0,0 @@ -import chalk from 'chalk'; -import { LogLevel, ILoggerOptions, ILogger } from './types'; - -const LogLevels: Readonly> = { - silent: 0, - error: 1, - warning: 3, - info: 4, - debug: 5, - verbose: 6, -}; - -const NUM_OF_MILLISEC_IN_SEC = BigInt(1000000); - -export class Logger implements ILogger { - constructor(public opts: ILoggerOptions) {} - - private times: Map = new Map(); - - timesLog: Map = new Map(); - - private output(level: LogLevel, ...message: string[]) { - if (getLogLevel(this.opts.level || 'info') < getLogLevel(level)) { - return; - } - - const format = () => { - if (this.opts.timestamp) { - return [`${chalk.dim(new Date().toLocaleTimeString())} ${message.join(' ')}`]; - } - return message; - }; - console.log(...format()); - } - - info(...msg: string[]) { - this.output('info', chalk.bold.blue('INFO'), ...msg); - } - - warn(...msg: string[]) { - this.output('warning', chalk.bold.yellow('WARN'), ...msg); - } - - error(...msg: string[]) { - this.output('error', chalk.bold.red('ERROR'), ...msg); - } - - debug(...info: string[]) { - this.output('debug', chalk.bold.magentaBright('DEBUG'), ...info); - } - - time(label: string) { - this.times.set(label, process.hrtime.bigint()); - } - - timeEnd(label: string) { - const time = process.hrtime.bigint(); - const start = this.times.get(label); - if (!start) { - throw new Error(`Time label '${label}' not found for Logger.timeEnd()`); - } - this.times.delete(label); - const diff = time - start; - const diffMs = Number(diff / NUM_OF_MILLISEC_IN_SEC); - this.timesLog.set(label, diffMs); - this.debug(`Time label ${label} took ${diffMs}ms`); - } -} - -export function createLogger(options: ILoggerOptions = { level: 'info', timestamp: false }) { - return new Logger(options); -} - -export function getLogLevel(logLevel: LogLevel): number { - return LogLevels[logLevel]; -} diff --git a/packages/libuild/libuild-core/src/plugins/asset.ts b/packages/libuild/libuild-core/src/plugins/asset.ts deleted file mode 100644 index 6641805da843..000000000000 --- a/packages/libuild/libuild-core/src/plugins/asset.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { basename, join, extname, relative, dirname, win32 } from 'path'; -import fs from 'fs'; -import { createHash } from 'crypto'; -import { resolvePathAndQuery } from '@modern-js/libuild-utils'; -import type { Loader } from 'esbuild'; -import { LibuildPlugin, ILibuilder, Asset } from '../types'; - -export const assetExt = [ - '.svg', - '.png', - '.jpg', - '.jpeg', - '.gif', - '.webp', - '.ttf', - '.otf', - '.woff', - '.woff2', - '.eot', - '.mp3', - '.mp4', - '.webm', - '.ogg', - '.wav', - '.flac', - '.aac', - '.mov', -]; -export const assetsPlugin = (): LibuildPlugin => { - const pluginName = 'libuild:asset'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.load.tapPromise(pluginName, async (args) => { - if (assetExt.find((ext) => ext === extname(args.path))) { - const { originalFilePath } = resolvePathAndQuery(args.path); - const { bundle, outdir, outbase } = compiler.config; - const rebaseFrom = bundle ? outdir : join(outdir, relative(outbase, dirname(args.path))); - - const { contents, loader } = await getAssetContents.apply(compiler, [originalFilePath, rebaseFrom, true]); - return { - contents, - loader, - }; - } - }); - }, - }; -}; - -// https://github.com/filamentgroup/directory-encoder/blob/master/lib/svg-uri-encoder.js -function encodeSVG(buffer: Buffer) { - return ( - encodeURIComponent( - buffer - .toString('utf-8') - // strip newlines and tabs - .replace(/[\n\r]/gim, '') - .replace(/\t/gim, ' ') - // strip comments - .replace(/))-->/gim, '') - // replace - .replace(/'/gim, '\\i') - ) - // encode brackets - .replace(/\(/g, '%28') - .replace(/\)/g, '%29') - ); -} - -/** - * - * @param this Compiler - * @param assetPath Absolute path of the asset - * @param rebaseFrom Absolute path of the file which use asset - * @param calledOnLoad called in load hooks - * @returns dataurl or path - */ -export async function getAssetContents( - this: ILibuilder, - assetPath: string, - rebaseFrom: string, - calledOnLoad?: boolean -) { - const fileContent = await fs.promises.readFile(assetPath); - const { bundle } = this.config; - const { name: assetName, limit, rebase, outdir, publicPath } = this.config.asset; - const outputFileName = getOutputFileName(assetPath, fileContent, assetName); - const outputFilePath = join(this.config.outdir, outdir, outputFileName); - const relativePath = relative(rebaseFrom, outputFilePath); - const normalizedRelativePath = normalizeSlashes(relativePath.startsWith('..') ? relativePath : `./${relativePath}`); - const normalizedPublicPath = `${ - typeof publicPath === 'function' ? publicPath(assetPath) : publicPath - }${outdir}/${outputFileName}`; - let emitAsset = true; - let contents: string | Buffer = normalizedPublicPath; - let loader: Loader = 'text'; - if (bundle) { - // inline base64 - if (fileContent.length <= limit) { - const mimetype = (await import('mime-types')).default.lookup(assetPath); - const isSVG = mimetype === 'image/svg+xml'; - const data = isSVG ? encodeSVG(fileContent) : fileContent.toString('base64'); - const encoding = isSVG ? '' : ';base64'; - contents = `data:${mimetype}${encoding},${data}`; - loader = 'text'; - emitAsset = false; - } else if (rebase) { - contents = calledOnLoad ? fileContent : normalizedRelativePath; - loader = calledOnLoad ? 'copy' : 'text'; - emitAsset = !calledOnLoad; - } - } else { - contents = normalizedRelativePath; - } - if (emitAsset) { - this.emitAsset(outputFilePath, { - type: 'asset', - fileName: outputFilePath, - contents: fileContent, - originalFileName: assetPath, - }); - } - return { - contents, - loader, - }; -} - -export function getOutputFileName(filePath: string, content: Buffer, assetName: Required): string { - const format = typeof assetName === 'function' ? assetName(filePath) : assetName; - const fileBaseNameArray = basename(filePath).split('.'); - const extname = fileBaseNameArray.pop(); - const fileBaseName = fileBaseNameArray.join('.'); - const outputFileName = format.replace(/(\[[^\]]*\])/g, (str: string, match: string): string => { - if (match === '[name]') { - return fileBaseName; - } - if (match === '[ext]') { - return extname as string; - } - if (match === '[hash]' || match === '[contenthash]') { - return getHash(content, null).slice(0, 8); - } - return match; - }); - - return outputFileName; -} - -export function getHash(content: Buffer | string, encoding: any, type = 'md5'): string { - return createHash(type).update(content.toString(), encoding).digest('hex'); -} - -function normalizeSlashes(file: string) { - return file.split(win32.sep).join('/'); -} diff --git a/packages/libuild/libuild-core/src/plugins/format-cjs.ts b/packages/libuild/libuild-core/src/plugins/format-cjs.ts deleted file mode 100644 index b6cfbdf7bfe3..000000000000 --- a/packages/libuild/libuild-core/src/plugins/format-cjs.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { transform } from 'sucrase'; -import { LibuildPlugin } from '../types'; - -export const formatCjsPlugin = (): LibuildPlugin => { - const pluginName = 'libuild:format-cjs'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.processAsset.tapPromise( - { name: pluginName }, - async chunk => { - if (chunk.fileName.endsWith('.js') && chunk.type === 'chunk') { - const code = chunk.contents.toString(); - const result = transform(code, { - transforms: ['imports'], - }); - return { - ...chunk, - contents: result.code, - map: result.sourceMap, - }; - } - return chunk; - }, - ); - }, - }; -}; diff --git a/packages/libuild/libuild-core/src/plugins/getInternalPlugin.ts b/packages/libuild/libuild-core/src/plugins/getInternalPlugin.ts deleted file mode 100644 index 11778487032e..000000000000 --- a/packages/libuild/libuild-core/src/plugins/getInternalPlugin.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { BuildConfig } from '../types'; -import { formatCjsPlugin } from './format-cjs'; -import { resolvePlugin } from './resolve'; -import { writeFilePlugin } from './write-file'; -import { cssPlugin } from './style'; -import { minifyPlugin } from './minify'; -import { assetsPlugin } from './asset'; - -export async function getInternalPlugin(config: BuildConfig) { - const internalPlugin = []; - - if (config.watch) { - const { watchPlugin } = await import('./watch'); - internalPlugin.push(watchPlugin()); - } - - internalPlugin.push(resolvePlugin(), assetsPlugin(), cssPlugin()); - - if (!config.bundle) { - const { redirectPlugin } = await import('./redirect'); - const { jsonPlugin } = await import('./json'); - internalPlugin.push(redirectPlugin(), jsonPlugin()); - } - - if (config.bundle && config.format === 'cjs' && config.splitting) { - internalPlugin.push(formatCjsPlugin()); - } - - internalPlugin.push(minifyPlugin(), writeFilePlugin()); - - if (config.metafile) { - const { metaFilePlugin } = await import('./metafile'); - internalPlugin.push(metaFilePlugin()); - } - - return internalPlugin; -} diff --git a/packages/libuild/libuild-core/src/plugins/json.ts b/packages/libuild/libuild-core/src/plugins/json.ts deleted file mode 100644 index 76cdcfe88176..000000000000 --- a/packages/libuild/libuild-core/src/plugins/json.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { readFileSync } from 'fs'; -import { LibuildPlugin } from '../types'; - -const isJsonExt = (path: string) => { - return path.endsWith('.json'); -}; - -/** - * only copy json file when bundle is false - */ -export const jsonPlugin = (): LibuildPlugin => { - const pluginName = 'libuild:json'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.load.tapPromise(pluginName, async args => { - if (isJsonExt(args.path)) { - return { - contents: readFileSync(args.path), - loader: 'copy', - }; - } - }); - }, - }; -}; diff --git a/packages/libuild/libuild-core/src/plugins/metafile.ts b/packages/libuild/libuild-core/src/plugins/metafile.ts deleted file mode 100644 index f608e0165127..000000000000 --- a/packages/libuild/libuild-core/src/plugins/metafile.ts +++ /dev/null @@ -1,21 +0,0 @@ -import path from 'path'; -import { LibuildPlugin } from '../types'; - -export const metaFilePlugin = (): LibuildPlugin => { - const pluginName = 'libuild:metafile'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.processAssets.tapPromise( - pluginName, - async (_chunk, manifest) => { - const now = Date.now(); - compiler.emitAsset( - path.resolve(compiler.config.outdir, `metafile-${now}.json`), - JSON.stringify(manifest.metafile, null, 2), - ); - }, - ); - }, - }; -}; diff --git a/packages/libuild/libuild-core/src/plugins/minify.ts b/packages/libuild/libuild-core/src/plugins/minify.ts deleted file mode 100644 index 2c95b0d7557a..000000000000 --- a/packages/libuild/libuild-core/src/plugins/minify.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { isObject, deepMerge } from '@modern-js/libuild-utils'; -import { - minify as terserMinify, - MinifyOptions as TerserMinifyOptions, -} from 'terser'; -import { ChunkType, LibuildPlugin, CLIConfig } from '../types'; -import { normalizeSourceMap } from '../utils'; - -export const minifyPlugin = (): LibuildPlugin => { - const pluginName = 'libuild:minify'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.processAsset.tapPromise(pluginName, async chunk => { - const { sourceMap, minify, target } = compiler.config; - if (chunk.type === ChunkType.chunk && minify !== 'esbuild') { - const code = chunk.contents.toString(); - const needSourceMap = Boolean(sourceMap); - if (minify) { - const terserOptions = resolveTerserOptions(minify, { - sourceMap: Boolean(needSourceMap), - target, - }); - const result = await terserMinify(code, { - ...terserOptions, - sourceMap: needSourceMap, - }); - return { - ...chunk, - contents: result.code || chunk.contents, - map: normalizeSourceMap(result.map as any, { needSourceMap }), - }; - } - } - return chunk; - }); - }, - }; -}; - -function resolveTerserOptions( - terserOptions: TerserMinifyOptions | 'terser', - { sourceMap, target }: { sourceMap: boolean; target: CLIConfig['target'] }, -): TerserMinifyOptions { - // cra: https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L237 - return deepMerge( - { - compress: { - ecma: target === 'es5' ? 5 : 2020, - inline: 2, - comparisons: false, - }, - format: { keep_quoted_props: true, comments: false }, - // Return object to avoid redundant `JSON.parse` in remapping - sourceMap: sourceMap - ? { - asObject: true, - // `includeSources` is not necessary for minification, - // and we can utilize this to reduce the size of the source map. - includeSources: false, - } - : false, - safari10: true, - toplevel: true, - }, - isObject(terserOptions) ? terserOptions : {}, - ); -} diff --git a/packages/libuild/libuild-core/src/plugins/resolve.ts b/packages/libuild/libuild-core/src/plugins/resolve.ts deleted file mode 100644 index 168d1404dc25..000000000000 --- a/packages/libuild/libuild-core/src/plugins/resolve.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { LibuildPlugin } from '../types'; -import { DATAURL_JAVASCRIPT_PATTERNS } from '../constants/regExp'; -import { isUrl } from '../bundler/resolve'; - -export const resolvePlugin = (): LibuildPlugin => { - const pluginName = 'libuild:resolve'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.resolve.tapPromise(pluginName, async args => { - if (isUrl(args.path)) { - // we only need to handle import| dynamic import and no need to handle require - const isImport = - args.kind === 'dynamic-import' || args.kind === 'import-statement'; - const isJavascript = DATAURL_JAVASCRIPT_PATTERNS.test(args.path); - return { - path: args.path, - external: !(isImport && isJavascript), - }; - } - const result = await compiler.resolve(args.path, { - kind: args.kind, - importer: args.importer, - resolveDir: args.resolveDir, - }); - - if ((result.path as any as boolean) === false) { - return { - path: '/empty-stub', - sideEffects: false, - }; - } - if (result.path) { - return result; - } - }); - compiler.hooks.load.tapPromise('libuild:resolve', async args => { - if (args.path === '/empty-stub') { - return { - contents: 'module.exports = {}', - }; - } - }); - }, - }; -}; diff --git a/packages/libuild/libuild-core/src/plugins/style/index.ts b/packages/libuild/libuild-core/src/plugins/style/index.ts deleted file mode 100644 index 9d0379ba37de..000000000000 --- a/packages/libuild/libuild-core/src/plugins/style/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { readFileSync } from 'fs'; -import { resolvePathAndQuery, isStyleExt } from '@modern-js/libuild-utils'; -import { identifier } from 'safe-identifier'; -import { Source, LibuildPlugin } from '../../types'; -import { transformStyle } from './transformStyle'; - -export const cssPlugin = (): LibuildPlugin => { - const cssVirtual = 'css_virtual'; - const pluginName = 'libuild:css'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.load.tapPromise(pluginName, async args => { - if (isStyleExt(args.path)) { - const { originalFilePath, query } = resolvePathAndQuery(args.path); - if (query.css_virtual) { - const contents = compiler.virtualModule.get(originalFilePath)!; - return { - contents, - loader: 'css', - }; - } - return { - contents: readFileSync(args.path), - loader: 'css', - }; - } - }); - compiler.hooks.transform.tapPromise( - pluginName, - async (source): Promise => { - if (isStyleExt(source.path)) { - const { query } = resolvePathAndQuery(source.path); - let { code, loader = 'css' } = source; - if (!query[cssVirtual]) { - ({ code, loader } = await transformStyle.apply(compiler, [ - source, - ])); - } - const { style, bundle } = compiler.config; - if (style.inject && bundle && loader === 'css') { - const styleInjectPath = require - .resolve('style-inject/dist/style-inject.es') - .replace(/[\\/]+/g, '/'); - const cssVariableName = identifier('css', true); - code = `var ${cssVariableName} = ${JSON.stringify( - code, - )};\nimport styleInject from '${styleInjectPath}';\nstyleInject(${cssVariableName});`; - loader = 'js'; - } - return { - ...source, - code, - loader, - }; - } - return source; - }, - ); - }, - }; -}; diff --git a/packages/libuild/libuild-core/src/plugins/watch.ts b/packages/libuild/libuild-core/src/plugins/watch.ts deleted file mode 100644 index 045b175bf1e3..000000000000 --- a/packages/libuild/libuild-core/src/plugins/watch.ts +++ /dev/null @@ -1,107 +0,0 @@ -import type { Stats } from 'fs'; -import path from 'path'; -import chokidar, { FSWatcher } from 'chokidar'; -import micromatch from 'micromatch'; -import { glob } from 'glob'; -import chalk from 'chalk'; -import { LibuildPlugin } from '../types'; - -export const watchPlugin = (): LibuildPlugin => { - const pluginName = 'libuild:watch'; - let watch: FSWatcher; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.initialize.tap(pluginName, () => { - watch = chokidar.watch([compiler.config.root], { - useFsEvents: false, // disable fsevents due to fsevents hoist problem - ignored: [ - '**/node_modules', - '**/.gitignore', - '**/.git', - compiler.config.outdir, - ], - cwd: compiler.config.root, - }); - compiler.watcher = watch; - let running = false; - let needReRun = false; - - const handleLink = async (filePath: string, type: 'add' | 'unlink') => { - const { userConfig, config } = compiler; - const { input: userInput } = userConfig; - const { bundle, root, input } = config; - const absFilePath = path.resolve(root, filePath); - let shouldRebuild = false; - if (Array.isArray(userInput) && !bundle) { - userInput.forEach(async i => { - const absGlob = path.resolve(root, i); - if (glob.hasMagic(absGlob)) { - micromatch.isMatch(absFilePath, absGlob) && - (shouldRebuild = true); - } else if (absFilePath.startsWith(absGlob)) { - shouldRebuild = true; - } - }); - } - if (shouldRebuild) { - const text = type === 'add' ? 'added' : 'unlinked'; - compiler.config.logger.info(`${chalk.underline(filePath)} ${text}`); - if (type === 'unlink') { - (input as string[]).splice( - (input as string[]).indexOf(filePath), - 1, - ); - } else { - (input as string[]).push(filePath); - } - if (running) { - needReRun = true; - } else { - running = true; - await compiler.compilation.reBuild('link'); - running = false; - if (needReRun) { - needReRun = false; - await compiler.compilation.reBuild('link'); - } - } - } - }; - const handleAdd = async (filePath: string) => { - return handleLink(filePath, 'add'); - }; - const handleUnlink = async (filePath: string) => { - return handleLink(filePath, 'unlink'); - }; - - const handleChange = async ( - filePath: string, - events: Stats, - ...args: any[] - ) => { - const { - config: { root }, - watchedFiles, - } = compiler; - if (watchedFiles.has(path.resolve(root, filePath))) { - compiler.config.logger.info(`${chalk.underline(filePath)} changed`); - compiler.hooks.watchChange.call([filePath]); - await compiler.compilation.reBuild('change'); - } - }; - watch.on('ready', () => { - watch.on('change', handleChange); - watch.on('add', handleAdd); - watch.on('unlink', handleUnlink); - }); - watch.once('restart', () => { - watch.removeListener('change', handleChange); - }); - }); - compiler.hooks.shutdown.tapPromise('watch', async () => { - await watch.close(); - }); - }, - }; -}; diff --git a/packages/libuild/libuild-core/src/plugins/write-file.ts b/packages/libuild/libuild-core/src/plugins/write-file.ts deleted file mode 100644 index 3ff3986df034..000000000000 --- a/packages/libuild/libuild-core/src/plugins/write-file.ts +++ /dev/null @@ -1,81 +0,0 @@ -import path from 'path'; -import fsExtra from 'fs-extra'; -import convertSourceMap from 'convert-source-map'; -import { Chunk, LibuildPlugin } from '../types'; - -const SOURCE_MAPPING_URL = 'sourceMappingURL'; - -function appendSourceMapURLLink(options: { filename: string; code: string }) { - return `${options.code}\n//# ${SOURCE_MAPPING_URL}=${options.filename}.map`; -} - -function appendSourceMapInline(options: { map: string; code: string }) { - return `${options.code}\n//# ${SOURCE_MAPPING_URL}=data:application/json;charset=utf-8;base64,${options.map}`; -} - -export const writeFilePlugin = (): LibuildPlugin => { - const pluignName = 'libuild:emit'; - return { - name: pluignName, - apply(compiler) { - let preOutputChunk: Map | null = null; - - function chunkHasChanged(key: string, chunk: Chunk) { - if (preOutputChunk) { - const preChunk = preOutputChunk.get(key); - if (preChunk && preChunk.contents === chunk.contents) { - return false; - } - } - return true; - } - - compiler.hooks.endCompilation.tapPromise(pluignName, async () => { - for (const [key, value] of compiler.outputChunk.entries()) { - if (!chunkHasChanged(key, value)) { - continue; - } - const absPath = path.resolve(compiler.config.outdir, key); - fsExtra.ensureDirSync(path.dirname(absPath)); - if (value.type === 'chunk' && value.map) { - if ( - compiler.config.sourceMap === false || - compiler.config.sourceMap === 'external' - ) { - await fsExtra.writeFile(absPath, value.contents); - } else if (compiler.config.sourceMap === true) { - await fsExtra.writeFile( - absPath, - appendSourceMapURLLink({ - code: value.contents, - filename: path.basename(absPath), - }), - ); - } else if (compiler.config.sourceMap === 'inline') { - await fsExtra.writeFile( - absPath, - appendSourceMapInline({ - code: value.contents, - map: convertSourceMap.fromObject(value.map).toBase64(), - }), - ); - } - - if ( - compiler.config.sourceMap === true || - compiler.config.sourceMap === 'external' - ) { - await fsExtra.writeFile( - `${absPath}.map`, - JSON.stringify(value.map), - ); - } - } else { - await fsExtra.writeFile(absPath, value.contents); - } - } - preOutputChunk = compiler.outputChunk; - }); - }, - }; -}; diff --git a/packages/libuild/libuild-core/src/types/builder.ts b/packages/libuild/libuild-core/src/types/builder.ts deleted file mode 100644 index 5a1217dbd195..000000000000 --- a/packages/libuild/libuild-core/src/types/builder.ts +++ /dev/null @@ -1,240 +0,0 @@ -import type { - Metafile, - OnResolveArgs, - OnLoadArgs, - OnResolveResult, - OnLoadResult, - BuildOptions, - Loader, -} from 'esbuild'; -import { - AsyncSeriesBailHook, - AsyncSeriesHook, - AsyncSeriesWaterfallHook, - SyncHook, -} from 'tapable'; -import { ImportKind } from 'esbuild'; -import { LibuildFailure } from '../error'; -import { CLIConfig, BuildConfig } from './config'; -import { Callback } from './callback'; -import { LibuildErrorInstance, LibuildErrorParams } from './error'; - -export interface ILibuilderHooks { - /** - * Asynchronous initialization. Executed after normalized `buildConfig` and `plugins`. - */ - initialize: AsyncSeriesHook<[], void>; - /** - * Equal to esbuild#onResolve and rollup#resolveId - */ - resolve: AsyncSeriesBailHook<[ResolveArgs], ResolveResult | undefined>; - /** - * Equal to esbuild#onLoad and rollup#load - */ - load: AsyncSeriesBailHook<[LoadArgs], LoadResult | undefined | void>; - /** - * - */ - transform: AsyncSeriesWaterfallHook; - /** - * Modify the chunk - */ - processAsset: AsyncSeriesWaterfallHook<[Chunk]>; - /** - * After esbuild onStart, also called by watchChange - */ - startCompilation: AsyncSeriesHook<[]>; - /** - * After esbuild onEnd, also called by watchChange - */ - endCompilation: AsyncSeriesHook<[LibuildFailure]>; - /** - * Post processing for assets - */ - processAssets: AsyncSeriesHook<[Map, LibuildManifest]>; - /** - * Watch related hook - */ - watchChange: SyncHook<[string[]]>; // we make this sync to compatible with rollup watchChange - /** - * Before close - */ - shutdown: AsyncSeriesHook<[]>; -} - -export declare interface ILibuilderStage { - /** - * Execute Before Internal Plugin - */ - PRE_INTERNAL: number; - /** - * Execute After Internal Plugin - */ - POST_INTERNAL: number; -} - -export interface BuilderResolveResult { - path: string; - suffix?: string; - external?: boolean; - sideEffects?: boolean; -} - -export interface BuilderResolveOptions { - kind?: ImportKind; - importer?: string; - resolveDir?: string; - skipSideEffects?: boolean; -} - -type LoadSvgrResult = { - contents: string; - loader: Loader; -}; - -export interface IBuilderBase { - build: () => Promise; - reBuild: (type: 'link' | 'change') => Promise; - close: (callack?: Callback) => void; -} - -export interface ILibuilder { - name?: string; - version: string; - compilation: IBuilderBase; - hooks: ILibuilderHooks; - STAGE: ILibuilderStage; - userConfig: CLIConfig; - config: BuildConfig; - plugins: LibuildPlugin[]; - outputChunk: Map; - virtualModule: Map; - init: (config: CLIConfig) => Promise; - build: () => Promise; - close: (callBack?: Callback) => Promise; - emitAsset: ((name: string, chunk: AssetChunk) => void) & - ((name: string, chunk: JsChunk) => void) & - ((name: string, chunk: string) => void); - watchedFiles: Set; - addWatchFile: (id: string) => void; - resolve: ( - source: string, - options?: BuilderResolveOptions, - ) => Promise; - loadSvgr: (path: string) => Promise; - getTransformContext: (path: string) => ITransformContext; - getSourcemapContext: (path: string) => ISourcemapContext; - report: (error: any) => void; - throw: (message: string, option: LibuildErrorParams) => void; - printErrors: () => void; - getErrors: () => LibuildFailure; - clearErrors: () => void; - removeError: (...errors: LibuildErrorInstance[]) => void; -} - -export interface ITransformContext extends ISourcemapContext { - addTransformResult: (pluginId: number, result: CacheValue) => void; - getValidCache: (pluginId: number, code: string) => undefined | CacheValue; -} - -export interface CacheValue extends Source { - originCode: string; -} - -export interface ISourcemapContext { - addSourceMap: (pluginId: number, map?: SourceMap) => void; - getInlineSourceMap: () => string; - getSourceMap: () => SourceMap | undefined; - getSourceMapChain: () => SourceMap[]; - genPluginId: (id: string) => number; -} - -export interface SourceMap { - mappings: string; - names: string[]; - sources: (string | null)[]; - version: number; - sourcesContent?: (string | null)[]; -} - -export type ExtraContext = Record; - -/** - * Only merge additional fields from U to T. - */ -export type SafeMerge = T & { - [K in keyof U as Exclude]: U[K]; -}; - -export interface LibuildPlugin { - name: string; - apply: (compiler: SafeMerge) => void; -} - -export type ResolveArgs = Pick< - OnResolveArgs, - 'importer' | 'path' | 'resolveDir' | 'kind' ->; -export type ResolveResult = Pick< - OnResolveResult, - 'path' | 'external' | 'namespace' | 'sideEffects' | 'suffix' ->; - -export type LoadArgs = Pick & - Pick; -export type LoadResult = Pick< - OnLoadResult, - 'contents' | 'loader' | 'resolveDir' -> & { - map?: SourceMap; -}; - -export type AssetChunk = { - type: 'asset'; - // eslint-disable-next-line node/prefer-global/buffer - contents: string | Buffer; - /** - * absolute file path - */ - fileName: string; - originalFileName?: string; - entryPoint?: string; -}; - -export type JsChunk = { - type: 'chunk'; - contents: string; - /** - * absolute file path - */ - fileName: string; - originalFileName?: string; - map?: SourceMap; - entryPoint?: string; - modules?: Record; - isEntry: boolean; -}; - -export type Chunk = AssetChunk | JsChunk; - -export type Source = { - code: string; - map?: SourceMap; - path: string; - loader?: string; - /** - * Whether enable cache. - * @default true - */ - cache?: boolean; -}; - -export const enum ChunkType { - chunk = 'chunk', - asset = 'asset', -} - -export type LibuildManifest = { - metafile: Metafile; - config: BuildOptions; -}; diff --git a/packages/libuild/libuild-core/src/types/callback.ts b/packages/libuild/libuild-core/src/types/callback.ts deleted file mode 100644 index 6ec23a069dca..000000000000 --- a/packages/libuild/libuild-core/src/types/callback.ts +++ /dev/null @@ -1 +0,0 @@ -export type Callback = (err?: any) => void; diff --git a/packages/libuild/libuild-core/src/types/config/asset.ts b/packages/libuild/libuild-core/src/types/config/asset.ts deleted file mode 100644 index fdc2d6f5953d..000000000000 --- a/packages/libuild/libuild-core/src/types/config/asset.ts +++ /dev/null @@ -1,16 +0,0 @@ -export type Asset = { - outdir?: string; - /** - * rebase relative url, default is true when format is 'cjs' or 'esm'. - */ - rebase?: boolean; - name?: string | ((filePath: string) => string); - /** - * Specify the limit size to inline - * @default 0 - */ - limit?: number; - publicPath?: string | ((filePath: string) => string); -}; - -export type AssetNormalized = Required; diff --git a/packages/libuild/libuild-core/src/types/config/index.ts b/packages/libuild/libuild-core/src/types/config/index.ts deleted file mode 100644 index 84f1dc592430..000000000000 --- a/packages/libuild/libuild-core/src/types/config/index.ts +++ /dev/null @@ -1,219 +0,0 @@ -import type { ImportKind, Loader, BuildOptions } from 'esbuild'; -import type { MinifyOptions as TerserMinifyOptions } from 'terser'; -import type { LogLevel, ILogger } from '../logger'; -import type { LibuildPlugin } from '../builder'; -import type { Resolve, ResolveNormalized } from './resolve'; -import type { Style } from './style'; -import type { Asset, AssetNormalized } from './asset'; - -export * from './resolve'; -export * from './style'; -export * from './asset'; - -type Minify = 'esbuild' | 'terser' | false | TerserMinifyOptions; - -export type Format = 'esm' | 'cjs' | 'umd' | 'iife'; - -type Input = - | { - [name: string]: string; - } - | string[]; - -type SourceMap = boolean | 'inline' | 'external'; - -type Globals = Record; - -type Define = Record; - -type External = (string | RegExp)[]; - -type Platform = 'node' | 'browser'; - -export type SideEffects = - | RegExp[] - | boolean - | ((id: string, external: boolean) => boolean); - -/** - * @experimental - */ -export type Redirect = { - alias?: boolean; - style?: boolean; - asset?: boolean; -}; - -export interface UserConfig { - /** - * @default true - */ - autoExternal?: - | boolean - | { - dependencies?: boolean; - peerDependencies?: boolean; - }; - /** - * @default true - */ - bundle?: boolean; - /** - * Input to the bundling algorithm. - * - * Only valid when bundle is 'true' - * @default { index: './src/index.ts '} - */ - input?: Input; - /** - * The directory for source. - * - * Only valid when bundle is 'false', it will transform all files in sourceDir - * @default 'src' - */ - sourceDir?: string; - /** - * The directory for output - * @default 'dist' - */ - outdir?: string; - /** - * @see https://esbuild.github.io/api/#outbase - * @default 'src' - */ - outbase?: string; - /** - * Options for esbuild, it may disable some of the functions of libuild - * @experimental - */ - esbuildOptions?: (options: BuildOptions) => BuildOptions; - /** - * @see https://esbuild.github.io/api/#entry-names - */ - entryNames?: string; - /** - * @see https://esbuild.github.io/api/#chunk-names - */ - chunkNames?: string; - /** - * Module format - * @default 'esm' - */ - format?: Format; - /** - * Code splitting - * @default false - */ - splitting?: boolean; - /** - * Minify JS - * @default false - */ - minify?: Minify; - /** - * When file changed builder will rebuild under watch mode. - * @default false - */ - watch?: boolean; - /** - * The level of the console log - * @default 'info' - */ - logLevel?: LogLevel; - /** - * Options for enhanced-resolve - */ - resolve?: Resolve; - /** - * Plugins for libuild - */ - plugins?: LibuildPlugin[]; - /** - * Compile target - * @see https://esbuild.github.io/api/#target - * @default 'es2015' - */ - target?: string; - /** - * The mode of sourcemap - * @default false - */ - sourceMap?: SourceMap; - /** - * Global variables, only used in umd format - * @default {} - */ - globals?: Globals; - /** - * Exclude it from your build - * Default Excluded your dependencies and peerDependencies - */ - external?: External; - /** - * @see https://esbuild.github.io/api/#define - */ - define?: Define; - /** - * @see https://esbuild.github.io/api/#platform - * @default 'node' - */ - platform?: Platform; - /** - * Emit esbuild metafile - * @see https://esbuild.github.io/api/#metafile - * @default false - */ - metafile?: boolean; - /** - * Options for style - */ - style?: Style; - /** - * Options for asset - */ - asset?: Asset; - /** - * @see https://esbuild.github.io/api/#loader - */ - loader?: Record; - /** - * @see https://esbuild.github.io/api/#inject - */ - inject?: string[]; - /** - * @see https://esbuild.github.io/api/#jsx - * @default 'automatic' - */ - jsx?: 'automatic' | 'preserve' | 'transform'; - /** - * Module sideEffects, it will invalidate the sideEffects field in package.json - */ - sideEffects?: SideEffects; - /** - * Redirect id when bundle is false - */ - redirect?: Redirect; - /** - * Cache for transform hooks, accelerate incremental build - * @default true - */ - transformCache?: boolean; -} - -export interface CLIConfig extends UserConfig { - /** - * project root dir - */ - root?: string; -} - -export interface BuildConfig - extends Required> { - chunkNames?: string; - sideEffects?: SideEffects; - logger: ILogger; - resolve: ResolveNormalized; - asset: AssetNormalized; - css_resolve: (id: string, dir: string) => string; - node_resolve: (id: string, dir: string, kind?: ImportKind) => string; -} diff --git a/packages/libuild/libuild-core/src/types/config/resolve.ts b/packages/libuild/libuild-core/src/types/config/resolve.ts deleted file mode 100644 index 95e60d904616..000000000000 --- a/packages/libuild/libuild-core/src/types/config/resolve.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Options for the resolver. - */ -export type Resolve = { - /** - * This is only valid for enhanced-resolve - */ - alias?: Record; - mainFields?: string[]; - /** - * @internal This is only valid for enhanced-resolve - */ - mainFiles?: string[]; - /** - * @internal This is only valid for enhanced-resolve - */ - preferRelative?: boolean; -}; - -export type ResolveNormalized = Required; diff --git a/packages/libuild/libuild-core/src/types/config/style.ts b/packages/libuild/libuild-core/src/types/config/style.ts deleted file mode 100644 index e6096c0aa7f6..000000000000 --- a/packages/libuild/libuild-core/src/types/config/style.ts +++ /dev/null @@ -1,71 +0,0 @@ -import type { AcceptedPlugin, ProcessOptions, Plugin } from 'postcss'; -import type { Options as sassOptions } from 'sass'; - -type LocalsConventionFunction = ( - originalClassName: string, - generatedClassName: string, - inputFile: string, -) => string; - -type GenerateScopedNameFunction = ( - name: string, - filename: string, - css: string, -) => string; - -declare class Loader { - finalSource?: string | undefined; - constructor(root: string, plugins: Plugin[]); - - fetch( - file: string, - relativeTo: string, - depTrace: string, - ): Promise<{ [key: string]: string }>; -} - -export type PostcssOptions = { - processOptions?: ProcessOptions; - plugins?: AcceptedPlugin[]; -}; - -export type { sassOptions }; - -type AdditionalData = string | ((filePath: string) => string); - -export interface Style { - inject?: boolean; - sass?: { - additionalData?: AdditionalData; - implementation?: object | string; - sassOptions?: sassOptions; - }; - less?: { - additionalData?: AdditionalData; - implementation?: object | string; - lessOptions?: Less.Options; - }; - postcss?: PostcssOptions; - autoModules?: boolean | RegExp; - modules?: { - localsConvention?: - | 'camelCase' - | 'camelCaseOnly' - | 'dashes' - | 'dashesOnly' - | LocalsConventionFunction; - scopeBehaviour?: 'global' | 'local'; - globalModulePaths?: RegExp[]; - generateScopedName?: string | GenerateScopedNameFunction; - hashPrefix?: string; - exportGlobals?: boolean; - root?: string; - resolve?: (file: string) => string | Promise; - Loader?: typeof Loader; - getJSON?: ( - cssFilename: string, - json: { [name: string]: string }, - outputFilename?: string, - ) => void; - }; -} diff --git a/packages/libuild/libuild-core/src/types/error.ts b/packages/libuild/libuild-core/src/types/error.ts deleted file mode 100644 index 99cf6c02092f..000000000000 --- a/packages/libuild/libuild-core/src/types/error.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Message } from 'esbuild'; - -export { Message as EsbuildError }; - -export interface EsbuildResultInfo { - errors: Message[]; - warnings: Message[]; -} - -export enum ErrorLevel { - Ignore, - Warn, - Error, -} - -export interface CodeFramePosition { - line: number; - column?: number; -} - -export interface CodeFrameFileOption { - filePath: string; -} - -export interface CodeFrameNormalOption { - filePath: string; - fileContent: string; - start?: CodeFramePosition; - end?: CodeFramePosition; -} - -/** - * Compatible with esbuild - */ -export interface CodeFrameLineOption { - filePath: string; - lineText: string; - start?: CodeFramePosition; - length?: number; -} - -export type CodeFrameOption = - | CodeFrameFileOption - | CodeFrameNormalOption - | CodeFrameLineOption; - -export interface ControllerOption { - /** - * No stack displayed - * @default `true` - */ - noStack?: boolean; - /** - * No color displayed - * @default `false` - */ - noColor?: boolean; -} - -export interface LibuildErrorInstance { - prefixCode?: string; - code: string; - message: string; - reason?: string; - stack?: string; - path?: string; - /** - * @default`'Error'` - */ - level?: keyof typeof ErrorLevel; - hint?: string; - referenceUrl?: string; - setControllerOption: (opt: ControllerOption) => void; - setCodeFrame: (opt: CodeFrameOption) => void; -} - -export type LibuildErrorParams = Omit< - LibuildErrorInstance, - | 'code' - | 'message' - | 'path' - | 'setControllerOption' - | 'setCodeFrame' - | 'toOverlayPayload' -> & { - code?: string; - controller?: ControllerOption; - codeFrame?: CodeFrameOption; -}; diff --git a/packages/libuild/libuild-core/src/types/global.d.ts b/packages/libuild/libuild-core/src/types/global.d.ts deleted file mode 100644 index 66e1626a1fdd..000000000000 --- a/packages/libuild/libuild-core/src/types/global.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'error-stack'; diff --git a/packages/libuild/libuild-core/src/types/index.ts b/packages/libuild/libuild-core/src/types/index.ts deleted file mode 100644 index 1ea86eaebdec..000000000000 --- a/packages/libuild/libuild-core/src/types/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './logger'; -export * from './config'; -export * from './builder'; -export * from './callback'; -export * from './error'; diff --git a/packages/libuild/libuild-core/src/types/logger.ts b/packages/libuild/libuild-core/src/types/logger.ts deleted file mode 100644 index 5ab76fcb948c..000000000000 --- a/packages/libuild/libuild-core/src/types/logger.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Options for log level. - */ -export type LogLevel = - | 'silent' - | 'error' - | 'warning' - | 'info' - | 'debug' - | 'verbose'; - -export interface ILoggerOptions { - /** - * @default 'info' - */ - level?: LogLevel; - /** - * @default false - */ - timestamp?: boolean; -} - -type Label = string; - -export abstract class ILogger { - abstract timesLog: Map; - - abstract info(...msg: string[]): void; - - abstract warn(...msg: string[]): void; - - abstract error(...msg: string[]): void; - - abstract debug(...msg: string[]): void; - - abstract time(label: Label): void; - - abstract timeEnd(label: Label): void; -} diff --git a/packages/libuild/libuild-core/src/utils/index.ts b/packages/libuild/libuild-core/src/utils/index.ts deleted file mode 100644 index 971eeea3cc90..000000000000 --- a/packages/libuild/libuild-core/src/utils/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './normalizeSourceMap'; -export * from './remapping'; -export * from './normalizeConfig'; diff --git a/packages/libuild/libuild-core/src/utils/normalizeConfig.ts b/packages/libuild/libuild-core/src/utils/normalizeConfig.ts deleted file mode 100644 index e4dee72a8888..000000000000 --- a/packages/libuild/libuild-core/src/utils/normalizeConfig.ts +++ /dev/null @@ -1,117 +0,0 @@ -import path from 'path'; -import { createLogger } from '../logger'; -import { DEFAULT_OUTBASE, DEFAULT_OUTDIR } from '../constants/config'; -import { createResolver, cssExtensions, jsExtensions } from '../core/resolve'; -import { CLIConfig, BuildConfig, LibuildPlugin, ResolveNormalized } from '../types'; - -export async function normalizeConfig(config: CLIConfig): Promise { - const root = config.root ?? process.cwd(); - const input = config.input ?? { - index: path.resolve(root, './src/index.ts'), - }; - const plugins: LibuildPlugin[] = config.plugins ?? []; - const logLevel = config.logLevel ?? 'info'; - const logger = createLogger({ level: logLevel }); - const platform = config.platform ?? 'node'; - const defaultMainFields = platform === 'node' ? ['module', 'main'] : ['module', 'browser', 'main']; - const resolve: ResolveNormalized = { - alias: config.resolve?.alias ?? {}, - mainFiles: config.resolve?.mainFiles ?? ['index'], - mainFields: config.resolve?.mainFields ?? defaultMainFields, - preferRelative: config.resolve?.preferRelative ?? false, - }; - const sourceMap = config.sourceMap ?? false; - const target = config.target ?? 'es2015'; - - const globals = config.globals ?? {}; - - const define = { - ...config.define, - }; - - const watch = config.watch ?? false; - const autoExternal = config.autoExternal ?? true; - const external = [ - ...(config.external ?? []), - ]; - const bundle = config.bundle ?? true; - const metafile = config.metafile ?? false; - const style = config.style ?? {}; - const loader = config.loader ?? {}; - const inject = config.inject ?? []; - const format = config.format ?? 'esm'; - const asset = { - limit: config.asset?.limit ?? 0, - outdir: config.asset?.outdir ?? 'assets', - rebase: config.asset?.rebase ?? (format === 'esm' || format === 'cjs'), - name: config.asset?.name ?? '[name].[hash].[ext]', - publicPath: config.asset?.publicPath ?? '', - }; - const minify = config.minify ?? false; - const splitting = config.splitting ?? false; - const outdir = path.resolve(root, config.outdir ?? DEFAULT_OUTDIR); - const outbase = path.resolve(root, config.outbase ?? DEFAULT_OUTBASE); - - const sourceDir = path.resolve(root, config.sourceDir ?? 'src'); - const entryNames = config.entryNames ?? (bundle ? '[name]' : '[dir]/[name]'); - const { chunkNames } = config; - const jsx = config.jsx ?? 'automatic'; - const esbuildOptions = config.esbuildOptions ?? ((config) => config); - const redirect = { - alias: config.redirect?.alias ?? true, - style: config.redirect?.style ?? true, - asset: config.redirect?.asset ?? true, - }; - const transformCache = config.transformCache ?? true; - - return { - transformCache, - redirect, - esbuildOptions, - jsx, - chunkNames, - inject, - loader, - metafile, - bundle, - style, - root, - resolve, - logLevel, - logger, - plugins, - target, - define, - sourceMap, - node_resolve: createResolver({ - resolveType: 'js', - root, - ...resolve, - platform, - extensions: jsExtensions, - }), - css_resolve: createResolver({ - resolveType: 'css', - root, - ...resolve, - platform, - preferRelative: true, - extensions: cssExtensions, - }), - input, - globals, - watch, - outdir, - outbase, - sourceDir, - minify, - splitting, - entryNames, - format, - external, - platform, - asset, - autoExternal, - sideEffects: config.sideEffects, - }; -} diff --git a/packages/libuild/libuild-core/src/utils/normalizeSourceMap.ts b/packages/libuild/libuild-core/src/utils/normalizeSourceMap.ts deleted file mode 100644 index 62e0c5aad96c..000000000000 --- a/packages/libuild/libuild-core/src/utils/normalizeSourceMap.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { RawSourceMap } from '@ampproject/remapping/dist/types/types'; -import { SourceMap } from '../types'; - -interface Options { - needSourceMap: boolean; -} - -export function normalizeSourceMap( - map: string | RawSourceMap | undefined, - opts?: Options, -): SourceMap | undefined { - if (opts?.needSourceMap === false || !map) { - return undefined; - } - if (typeof map === 'string') { - return JSON.parse(map); - } - return map; -} diff --git a/packages/libuild/libuild-core/test/dts/define-config.test-d.ts b/packages/libuild/libuild-core/test/dts/define-config.test-d.ts deleted file mode 100644 index 1ab91f106ae5..000000000000 --- a/packages/libuild/libuild-core/test/dts/define-config.test-d.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { expectType, expectAssignable, expectNotAssignable } from 'tsd'; - -import { defineConfig, UserConfig } from '../../dist'; - -describe('Partial UserConfig', () => { - const EMPTY_USER_CONFIG: {} = {}; - const PARTIAL_USER_CONFIG: Partial = {}; - const PARTIAL_USER_CONFIG_LIST: Partial[] = []; - - expectAssignable(PARTIAL_USER_CONFIG); - - expectAssignable(PARTIAL_USER_CONFIG_LIST); - expectType(defineConfig(EMPTY_USER_CONFIG)); - expectType(defineConfig([])); -}); - -declare const VALID_USER_CONFIG_LIST: [ - { - input: { - aaa: 'aaa'; - bbb: 'bbb'; - }; - }, - { - outdir: 'test'; - chunkNames: 'chunkNames'; - }, - { - path: undefined; - chunkNames: undefined; - }, - { - watch: true | false; - }, - { - logLevel: 'silent' | 'error' | 'warning' | 'info' | 'debug' | 'verbose'; - }, - { - resolve: { - alias: { - '@/src': 'src'; - }; - mainFields: undefined | [] | ['source', 'module', 'main']; - mainFiles: undefined | [] | ['index']; - preferRelative: undefined | true | false; - }; - }, - { - plugins: [ - { - name: 'plugin'; - apply: () => void; - } - ]; - }, - { - target: 'es5' | 'es6'; - }, - { - sourceMap: 'inline' | 'external' | true | false; - }, - { - external: [] | ['@modern-js/libuild']; - }, - { - platform: 'node' | 'browser'; - }, - { - metafile: true | false; - }, - { - style: { - less: { - additionalData: ''; - }; - sass: { - additionalData: ''; - }; - postcss: { - processOptions: {}; - plugins: []; - }; - cleanCss: true | false; - }; - } -]; - -describe('Valid user configs', () => { - expectAssignable>(VALID_USER_CONFIG_LIST); -}); - -declare const INVALID_USER_CONFIG_LIST: [ - { - mode: 'aaa' | 'bbb'; - }, - { - input: 'aaa'; - }, - { - outdir: 123; - }, - { - resolve: false | true; - }, - { - profile: 'libuild'; - }, - { - logLevel: 'aaa'; - }, - { - minify: true; - }, - { - target: 'es2021'; - }, - { - style: true; - } -]; - -describe('Invalid user config', () => { - expectNotAssignable>(INVALID_USER_CONFIG_LIST); -}); diff --git a/packages/libuild/libuild-core/test/dts/exist.test-d.ts b/packages/libuild/libuild-core/test/dts/exist.test-d.ts deleted file mode 100644 index de17d50224f2..000000000000 --- a/packages/libuild/libuild-core/test/dts/exist.test-d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { expectType } from 'tsd'; - -import { - defineConfig as rawDefineConfig, - formatError as rawFormatError, - isLibuildErrorInstance as rawIsLibuildErrorInstance, - warpErrors as rawPrintError, - loadConfig as rawLoadConfig, - run as rawRun, - LibuildError, - Libuilder, -} from '../../dist'; - -declare const defineConfig: typeof rawDefineConfig; -expectType(defineConfig); - -declare const formatError: typeof rawFormatError; -expectType(formatError); - -declare const isLibuildErrorInstance: typeof rawIsLibuildErrorInstance; -expectType(isLibuildErrorInstance); - -declare const loadConfig: typeof rawLoadConfig; -expectType(loadConfig); - -declare const printError: typeof rawPrintError; -expectType(printError); - -declare const run: typeof rawRun; -expectType(run); - -declare const libuildBundler: Libuilder; -expectType(libuildBundler); - -declare const libuildError: LibuildError; -expectType(libuildError); diff --git a/packages/libuild/libuild-core/test/unit/findEntry.test.ts b/packages/libuild/libuild-core/test/unit/findEntry.test.ts deleted file mode 100644 index c9d9499ab39a..000000000000 --- a/packages/libuild/libuild-core/test/unit/findEntry.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import assert from 'assert'; -import { findEntry } from '../../src/bundler/adapter'; - -describe('findEntry', () => { - it('default', () => { - const entries = ['a.js', 'a-b.js']; - assert(findEntry(entries, 'a.css') === 'a.js'); - assert(findEntry(entries, 'a-b.css') === 'a-b.js'); - }); -}); diff --git a/packages/libuild/libuild-core/test/unit/getAllDep.test.ts b/packages/libuild/libuild-core/test/unit/getAllDep.test.ts deleted file mode 100644 index 0e9f6eee0362..000000000000 --- a/packages/libuild/libuild-core/test/unit/getAllDep.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import assert from 'assert'; -import { getAllDeps } from '../../src/utils'; - -describe('getAllDeps', () => { - it('default', () => { - const { dep } = getAllDeps(process.cwd(), true); - assert(dep.indexOf('esbuild') > -1); - }); - it('bundle dep', () => { - const { dep } = getAllDeps(process.cwd(), { dependencies: false }); - assert(dep.indexOf('esbuild') === -1); - }); -}); diff --git a/packages/libuild/libuild-core/test/unit/style/rebaseUrl.test.ts b/packages/libuild/libuild-core/test/unit/style/rebaseUrl.test.ts deleted file mode 100644 index 9e62ed99f945..000000000000 --- a/packages/libuild/libuild-core/test/unit/style/rebaseUrl.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import path from 'path'; -import assert from 'assert'; -import { rebaseUrls } from '../../../src/plugins/style/utils'; - -describe('rebase', () => { - it('rebaseUrl', async () => { - const rootFile = path.resolve(__dirname, 'index.less'); - const file = path.resolve(__dirname, 'less/common.less'); - const result = await rebaseUrls(file, path.dirname(rootFile), (id: string, dir: string) => { - return path.resolve(dir, id); - }); - assert(result.contents?.includes?.('less/a.png'), 'rewrite url'); - }); - it('rebaseUrl original', async () => { - const rootFile = path.resolve(__dirname, 'index.less'); - const file = path.resolve(__dirname, 'index.less'); - const result = await rebaseUrls(file, path.dirname(rootFile), (id: string, dir: string) => { - return path.resolve(dir, id); - }); - - assert(result.contents == null, 'rewrite url'); - }); - it('rebase with absolute url', async () => { - const rootFile = path.resolve(__dirname, 'index.less'); - const file = path.resolve(__dirname, 'less/absolute.less'); - const result = await rebaseUrls(file, path.dirname(rootFile), (id: string, dir: string) => { - return path.resolve(dir, id); - }); - assert(result.contents?.includes?.('/a.png'), 'rewrite url with absolute url'); - }); - it('do not replace variable', async () => { - const rootFile = path.resolve(__dirname, 'index.less'); - const file = path.resolve(__dirname, 'less/variable.less'); - let replace = false; - await rebaseUrls(file, path.dirname(rootFile), (id: string, dir: string) => { - replace = true; - return path.resolve(dir, id); - }); - assert(!replace); - }); -}); diff --git a/packages/libuild/libuild-core/tsconfig.build.json b/packages/libuild/libuild-core/tsconfig.build.json deleted file mode 100644 index 1e2a0b909941..000000000000 --- a/packages/libuild/libuild-core/tsconfig.build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src"], - "compilerOptions": { - "rootDir": "src", - "declarationMap": true, - "declaration": true, - "emitDeclarationOnly": true - } -} diff --git a/packages/libuild/libuild-core/tsconfig.json b/packages/libuild/libuild-core/tsconfig.json deleted file mode 100644 index 4ab28802840b..000000000000 --- a/packages/libuild/libuild-core/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@modern-js/tsconfig/base", - "compilerOptions": { - "baseUrl": "src", - "outDir": "lib", - "rootDir": ".", - "module": "CommonJS", - "types": ["mocha", "less"] - }, - "include": ["src", "test", "scripts"] -} diff --git a/packages/libuild/libuild-plugin-babel/.eslintrc.cjs b/packages/libuild/libuild-plugin-babel/.eslintrc.cjs deleted file mode 100644 index 3041232d1716..000000000000 --- a/packages/libuild/libuild-plugin-babel/.eslintrc.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['@modern-js/eslint-config'], -}; diff --git a/packages/libuild/libuild-plugin-babel/CHANGELOG.md b/packages/libuild/libuild-plugin-babel/CHANGELOG.md deleted file mode 100644 index 369dd2296528..000000000000 --- a/packages/libuild/libuild-plugin-babel/CHANGELOG.md +++ /dev/null @@ -1,33 +0,0 @@ -# @modern-js/libuild-plugin-babel - -## 2.35.1 - -## 2.35.0 - -## 2.34.0 - -## 2.33.1 - -## 2.33.0 - -## 2.32.1 - -## 2.32.0 - -## 2.31.2 - -## 2.31.1 - -## 2.31.0 - -## 2.30.0 - -### Patch Changes - -- 7cb7b24: chore(libuild): bump typescript v5 and some other devDependencies - - chore(libuild): 升级 typescript v5 和其他 devDependencies - -- 3e67a4e: chore(libuild): remove some unused dev dependencies - - chore(libuild): 移除一些无用的 dev dependencies diff --git a/packages/libuild/libuild-plugin-babel/README.md b/packages/libuild/libuild-plugin-babel/README.md deleted file mode 100644 index 455301427a66..000000000000 --- a/packages/libuild/libuild-plugin-babel/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# @modern-js/libuild-plugin-babel -[![npm version](https://badge.fury.io/js/@modern-js%2Flibuild-plugin-babel.svg)](https://www.npmjs.com/package/@modern-js/libuild-plugin-babel) - -A plugin for libuild to transform your code with babel. - -## Tips -For compatibility with older applications, Libuild also supports user-defined Babel configurations, such as specifying additional babel plugins and babel presets, but please note: **Using Babel will result in slower builds, so do not use Babel unless necessary**. - -Neither `.babelrc` nor `babel.config.js` in the project root will take effect. If you need to use Babel, you need to configure it in the `libuild.config.ts` file. - -## Usage - -```ts -// libuild.config.ts -import { defineConfig } from '@modern-js/libuild'; -import { babelPlugin } from '@modern-js/libuild-plugin-babel'; - -export = defineConfig({ - plugins:[ - babelPlugin( { /* options here */ }) - ] -}) -``` - - -## Options - -See here for [babel transform options](https://babeljs.io/docs/en/options) \ No newline at end of file diff --git a/packages/libuild/libuild-plugin-babel/modern.config.js b/packages/libuild/libuild-plugin-babel/modern.config.js deleted file mode 100644 index 9acddbc5d920..000000000000 --- a/packages/libuild/libuild-plugin-babel/modern.config.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - buildConfig: [ - { - format: 'cjs', - target: 'es2019', - dts: false - }, { - buildType: 'bundleless', - dts: { - only: true - } - } - ] -}; - diff --git a/packages/libuild/libuild-plugin-babel/package.json b/packages/libuild/libuild-plugin-babel/package.json deleted file mode 100644 index 13fdd7fbc196..000000000000 --- a/packages/libuild/libuild-plugin-babel/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "@modern-js/libuild-plugin-babel", - "version": "2.35.1", - "description": "A plugin for libuild to transform your code with babel", - "keywords": [ - "libuild", - "babel" - ], - "repository": "modern-js-dev/libuild", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "modern-lib build", - "dev": "modern-lib build --watch" - }, - "license": "ISC", - "devDependencies": { - "@modern-js/eslint-config": "workspace:*", - "@modern-js/libuild": "workspace:*", - "@modern-js/libuild-utils": "workspace:*", - "@scripts/build": "workspace:*", - "typescript": "^5", - "@types/node": "12.20.42", - "@types/babel__core": "7.1.16" - }, - "dependencies": { - "@babel/core": "^7.22.15", - "@swc/helpers": "0.5.1" - } -} diff --git a/packages/libuild/libuild-plugin-babel/src/index.ts b/packages/libuild/libuild-plugin-babel/src/index.ts deleted file mode 100644 index a87c869fdec8..000000000000 --- a/packages/libuild/libuild-plugin-babel/src/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { LibuildPlugin } from '@modern-js/libuild'; -import type { TransformOptions as BabelTransformOptions } from '@babel/core'; -import { isJsExt, resolvePathAndQuery, isJsLoader } from '@modern-js/libuild-utils'; - -export const babelPlugin = (options: BabelTransformOptions): LibuildPlugin => { - return { - name: 'libuild:babel', - apply(compiler) { - if (options) { - compiler.hooks.transform.tapPromise('babel', async (args) => { - const { originalFilePath } = resolvePathAndQuery(args.path); - if (isJsExt(originalFilePath) || isJsLoader(args.loader)) { - const result = await require('@babel/core').transformAsync(args.code, { - filename: originalFilePath, - sourceFileName: originalFilePath, - sourceMaps: Boolean(compiler.config.sourceMap), - sourceType: 'unambiguous', - inputSourceMap: false, - babelrc: false, - configFile: false, - compact: false, - exclude: [/\bcore-js\b/], - ...options, - }); - return { - ...args, - code: result?.code, - map: result?.map, - }; - } - return args; - }); - } - }, - }; -}; diff --git a/packages/libuild/libuild-plugin-babel/tsconfig.json b/packages/libuild/libuild-plugin-babel/tsconfig.json deleted file mode 100644 index b33811636fcc..000000000000 --- a/packages/libuild/libuild-plugin-babel/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@modern-js/tsconfig/base", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "declaration": true, - "emitDeclarationOnly": true - }, - "include": ["src"], - "exclude": ["node_modules"] -} diff --git a/packages/libuild/libuild-plugin-node-polyfill/.eslintrc.cjs b/packages/libuild/libuild-plugin-node-polyfill/.eslintrc.cjs deleted file mode 100644 index 3041232d1716..000000000000 --- a/packages/libuild/libuild-plugin-node-polyfill/.eslintrc.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['@modern-js/eslint-config'], -}; diff --git a/packages/libuild/libuild-plugin-node-polyfill/CHANGELOG.md b/packages/libuild/libuild-plugin-node-polyfill/CHANGELOG.md deleted file mode 100644 index cc92d41f6152..000000000000 --- a/packages/libuild/libuild-plugin-node-polyfill/CHANGELOG.md +++ /dev/null @@ -1,43 +0,0 @@ -# @modern-js/libuild-plugin-node-polyfill - -## 2.35.1 - -### Patch Changes - -- 6893765: fix(libuild-plugin-node-polyfill): fix error resolve path - fix(libuild-plugin-node-polyfill): 修复错误的解析路径 - -## 2.35.0 - -## 2.34.0 - -## 2.33.1 - -## 2.33.0 - -### Patch Changes - -- af1ad38: fix: incorrect output - fix: 修复错误的产物 - -## 2.32.1 - -## 2.32.0 - -## 2.31.2 - -## 2.31.1 - -## 2.31.0 - -## 2.30.0 - -### Patch Changes - -- 7cb7b24: chore(libuild): bump typescript v5 and some other devDependencies - - chore(libuild): 升级 typescript v5 和其他 devDependencies - -- 3e67a4e: chore(libuild): remove some unused dev dependencies - - chore(libuild): 移除一些无用的 dev dependencies diff --git a/packages/libuild/libuild-plugin-node-polyfill/README.md b/packages/libuild/libuild-plugin-node-polyfill/README.md deleted file mode 100644 index 7764f6df6700..000000000000 --- a/packages/libuild/libuild-plugin-node-polyfill/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# @modern-js/libuild-plugin-babel -[![npm version](https://badge.fury.io/js/@modern-js%2Flibuild-plugin-node-polyfill.svg)](https://www.npmjs.com/package/@modern-js/libuild-plugin-node-polyfill) - -A plugin for libuild includes node polyfill - -## Usage - -```ts -// libuild.config.ts -import { defineConfig } from '@modern-js/libuild'; -import { nodePolyfillPlugin } from '@modern-js/libuild-plugin-node-polyfill'; - -export = defineConfig({ - plugins:[ - nodePolyfillPlugin( { /* options here */ }) - ] -}) -``` - - -## Options - -### excludes -The exclude option is a string array about polyfill modules, this modules will be not injected, default is `undefined` diff --git a/packages/libuild/libuild-plugin-node-polyfill/modern.config.js b/packages/libuild/libuild-plugin-node-polyfill/modern.config.js deleted file mode 100644 index 808f9f9dbab7..000000000000 --- a/packages/libuild/libuild-plugin-node-polyfill/modern.config.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = { - buildConfig: [ - { - format: 'cjs', - target: 'es2019', - dts: false, - }, - { - buildType: 'bundleless', - dts: { - only: true, - }, - }, - { - target: 'esnext', - format: 'esm', - input: ['./src/mock/*'], - outDir: 'dist/mock', - dts: false, - }, - { - target: 'esnext', - format: 'esm', - input: ['./src/globals.js'], - dts: false, - }, - ], -}; diff --git a/packages/libuild/libuild-plugin-node-polyfill/package.json b/packages/libuild/libuild-plugin-node-polyfill/package.json deleted file mode 100644 index 4a8745774f65..000000000000 --- a/packages/libuild/libuild-plugin-node-polyfill/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@modern-js/libuild-plugin-node-polyfill", - "version": "2.35.1", - "description": "A plugin for libuild includes node polyfill", - "keywords": [ - "libuild", - "node", - "polyfill" - ], - "repository": "modern-js-dev/libuild", - "license": "MIT", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "modern-lib build", - "dev": "modern-lib build --watch" - }, - "dependencies": { - "@swc/helpers": "0.5.1", - "assert": "2.0.0", - "browserify-zlib": "0.2.0", - "buffer": "6.0.3", - "console-browserify": "1.2.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "domain-browser": "4.19.0", - "events": "3.3.0", - "filter-obj": "2.0.2", - "https-browserify": "1.0.0", - "os-browserify": "0.3.0", - "path-browserify": "1.0.1", - "process": "0.11.10", - "punycode": "2.1.1", - "querystring-es3": "0.2.1", - "readable-stream": "3.6.0", - "stream-browserify": "3.0.0", - "stream-http": "3.2.0", - "string_decoder": "1.3.0", - "timers-browserify": "2.0.12", - "tty-browserify": "0.0.1", - "url": "0.11.0", - "util": "0.12.4", - "vm-browserify": "1.1.2" - }, - "devDependencies": { - "@modern-js/eslint-config": "workspace:*", - "@modern-js/libuild": "workspace:*", - "@scripts/build": "workspace:*", - "typescript": "^5" - } -} diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/index.ts b/packages/libuild/libuild-plugin-node-polyfill/src/index.ts deleted file mode 100644 index 4af0b78535c8..000000000000 --- a/packages/libuild/libuild-plugin-node-polyfill/src/index.ts +++ /dev/null @@ -1,112 +0,0 @@ -import path from 'path'; -import type { LibuildPlugin } from '@modern-js/libuild'; - -export interface NodePolyfillPluginOptions { - // like https://github.com/Richienb/node-polyfill-webpack-plugin#excludealiases - excludes?: string[]; - // override built-in node polyfill config, such as `fs`. - overrides?: Partial>; -} -function filterObject(object: Record, filter: (id: string) => boolean) { - const filtered: Record = {}; - Object.keys(object).forEach((key) => { - if (filter(key)) { - filtered[key] = object[key]; - } - }); - return filtered; -} -function excludeObjectKeys(object: Record, keys: string[]) { - return filterObject(object, (key) => !keys.includes(key)); -} - -function addResolveFallback(object: Record, overrides: Record = {}) { - const keys = Object.keys(object); - const newObject: Record = {}; - for (const key of keys) { - if (object[key] === null) { - newObject[key] = path.join(__dirname, `./mock/${key}.js`); - } else { - newObject[key] = object[key] as string; - } - } - - const overridesKeys = Object.keys(overrides); - for (const key of overridesKeys) { - if (overrides[key]) { - newObject[key] = overrides[key]; - } - } - - return newObject; -} - -export const modules = { - assert: require.resolve('assert/'), - buffer: require.resolve('buffer/'), - child_process: null, - cluster: null, - console: require.resolve('console-browserify'), - constants: require.resolve('constants-browserify'), - crypto: require.resolve('crypto-browserify'), - dgram: null, - dns: null, - domain: require.resolve('domain-browser'), - events: require.resolve('events/'), - fs: null, - http: require.resolve('stream-http'), - https: require.resolve('https-browserify'), - module: null, - net: null, - os: require.resolve('os-browserify/browser'), - path: require.resolve('path-browserify'), - punycode: require.resolve('punycode/'), - process: require.resolve('process/browser'), - querystring: require.resolve('querystring-es3'), - readline: null, - repl: null, - stream: require.resolve('stream-browserify'), - _stream_duplex: require.resolve('readable-stream/lib/_stream_duplex'), - _stream_passthrough: require.resolve('readable-stream/lib/_stream_passthrough'), - _stream_readable: require.resolve('readable-stream/lib/_stream_readable'), - _stream_transform: require.resolve('readable-stream/lib/_stream_transform'), - _stream_writable: require.resolve('readable-stream/lib/_stream_writable'), - string_decoder: require.resolve('string_decoder/'), - sys: require.resolve('util/'), - timers: require.resolve('timers-browserify'), - tls: null, - tty: require.resolve('tty-browserify'), - url: require.resolve('url/'), - util: require.resolve('util/'), - vm: require.resolve('vm-browserify'), - zlib: require.resolve('browserify-zlib'), -}; - -export const nodePolyfillPlugin = (options: NodePolyfillPluginOptions): LibuildPlugin => { - return { - name: 'libuild:@modern-js/libuild-plugin-node-polyfill', - apply(compiler) { - options = { - excludes: [], - ...options, - }; - // plugin logic here - const polyfillModules = { - ...excludeObjectKeys(addResolveFallback(modules, options.overrides), options.excludes ?? []), - }; - const polyfillModulesKeys = Object.keys(polyfillModules); - compiler.hooks.resolve.tap('nodePolyfill', (args) => { - if (polyfillModulesKeys.includes(args.path)) { - return { - path: polyfillModules[args.path], - }; - } - }); - - // globals - if (typeof compiler.config === 'object') { - compiler.config.inject = [...(compiler.config.inject ?? []), path.join(__dirname, 'globals.js')]; - } - }, - }; -}; diff --git a/packages/libuild/libuild-plugin-node-polyfill/tsconfig.json b/packages/libuild/libuild-plugin-node-polyfill/tsconfig.json deleted file mode 100644 index b33811636fcc..000000000000 --- a/packages/libuild/libuild-plugin-node-polyfill/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@modern-js/tsconfig/base", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "declaration": true, - "emitDeclarationOnly": true - }, - "include": ["src"], - "exclude": ["node_modules"] -} diff --git a/packages/libuild/libuild-plugin-svgr/.eslintrc.cjs b/packages/libuild/libuild-plugin-svgr/.eslintrc.cjs deleted file mode 100644 index 3041232d1716..000000000000 --- a/packages/libuild/libuild-plugin-svgr/.eslintrc.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['@modern-js/eslint-config'], -}; diff --git a/packages/libuild/libuild-plugin-svgr/CHANGELOG.md b/packages/libuild/libuild-plugin-svgr/CHANGELOG.md deleted file mode 100644 index 731754cccf72..000000000000 --- a/packages/libuild/libuild-plugin-svgr/CHANGELOG.md +++ /dev/null @@ -1,33 +0,0 @@ -# @modern-js/libuild-plugin-svgr - -## 2.35.1 - -## 2.35.0 - -## 2.34.0 - -## 2.33.1 - -## 2.33.0 - -## 2.32.1 - -## 2.32.0 - -## 2.31.2 - -## 2.31.1 - -## 2.31.0 - -## 2.30.0 - -### Patch Changes - -- 7cb7b24: chore(libuild): bump typescript v5 and some other devDependencies - - chore(libuild): 升级 typescript v5 和其他 devDependencies - -- 3e67a4e: chore(libuild): remove some unused dev dependencies - - chore(libuild): 移除一些无用的 dev dependencies diff --git a/packages/libuild/libuild-plugin-svgr/README.md b/packages/libuild/libuild-plugin-svgr/README.md deleted file mode 100644 index f9dd2b536a9a..000000000000 --- a/packages/libuild/libuild-plugin-svgr/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# @modern-js/libuild-plugin-svgr -[![npm version](https://badge.fury.io/js/@modern-js%2Flibuild-plugin-svgr.svg)](https://www.npmjs.com/package/@modern-js/libuild-plugin-svgr) - -A plugin for libuild to transform your svg to react component - -## Usage - -```ts -// libuild.config.ts -import { defineConfig } from '@modern-js/libuild'; -import { svgrPlugin } from '@modern-js/libuild-plugin-svgr'; - -export = defineConfig({ - plugins:[ - svgrPlugin( { /* options here */ }) - ] -}) -``` - -## Options - -### include -The include option is a glob pattern to match the svg files you want to transform, default is `/\.(svg)$/` - -### exclude -The exclude option is a glob pattern to match the svg files you don't want to transform, default is `undefined` - -### other options - -See here for [svgr options](https://react-svgr.com/docs/options/) \ No newline at end of file diff --git a/packages/libuild/libuild-plugin-svgr/modern.config.js b/packages/libuild/libuild-plugin-svgr/modern.config.js deleted file mode 100644 index 9acddbc5d920..000000000000 --- a/packages/libuild/libuild-plugin-svgr/modern.config.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - buildConfig: [ - { - format: 'cjs', - target: 'es2019', - dts: false - }, { - buildType: 'bundleless', - dts: { - only: true - } - } - ] -}; - diff --git a/packages/libuild/libuild-plugin-svgr/package.json b/packages/libuild/libuild-plugin-svgr/package.json deleted file mode 100644 index c16413ad91c2..000000000000 --- a/packages/libuild/libuild-plugin-svgr/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@modern-js/libuild-plugin-svgr", - "version": "2.35.1", - "description": "A plugin for libuild to transform your svg to react component", - "keywords": [ - "libuild", - "svgr" - ], - "repository": "modern-js-dev/libuild", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "modern-lib build", - "dev": "modern-lib build --watch" - }, - "license": "MIT", - "dependencies": { - "@swc/helpers": "0.5.1", - "@svgr/core": "8.0.0", - "@svgr/plugin-jsx": "8.0.1", - "@svgr/plugin-svgo": "8.0.1", - "rollup-pluginutils": "2.8.2" - }, - "devDependencies": { - "@types/node": "12.20.42", - "typescript": "^5", - "@modern-js/eslint-config": "workspace:*", - "@modern-js/libuild": "workspace:*", - "@scripts/build": "workspace:*" - } -} diff --git a/packages/libuild/libuild-plugin-svgr/src/index.ts b/packages/libuild/libuild-plugin-svgr/src/index.ts deleted file mode 100644 index 35d366be1b7a..000000000000 --- a/packages/libuild/libuild-plugin-svgr/src/index.ts +++ /dev/null @@ -1,43 +0,0 @@ -import fs from 'fs'; -import { transform, Config } from '@svgr/core'; -import { createFilter, CreateFilter } from 'rollup-pluginutils'; -import svgo from '@svgr/plugin-svgo'; -import jsx from '@svgr/plugin-jsx'; -import type { LibuildPlugin } from '@modern-js/libuild'; - -export interface Options extends Config { - include?: Parameters[0]; - exclude?: Parameters[1]; -} - -const PLUGIN_NAME = 'libuild:svgr'; -const SVG_REGEXP = /\.svg$/; - -export const svgrPlugin = (options: Options = {}): LibuildPlugin => { - const filter = createFilter(options.include || SVG_REGEXP, options.exclude); - return { - name: PLUGIN_NAME, - apply(compiler) { - compiler.loadSvgr = async (path: string) => { - if (!filter(path)) return; - const loader = 'jsx'; - const text = fs.readFileSync(path.split('?')[0], 'utf8'); - const jsCode = await transform(text, options, { - filePath: path, - caller: { - name: PLUGIN_NAME, - defaultPlugins: [svgo, jsx], - }, - }); - return { - contents: jsCode, - loader, - }; - }; - compiler.hooks.load.tapPromise(PLUGIN_NAME, async (args) => { - const result = await compiler.loadSvgr(args.path); - return result; - }); - }, - }; -}; diff --git a/packages/libuild/libuild-plugin-svgr/tsconfig.json b/packages/libuild/libuild-plugin-svgr/tsconfig.json deleted file mode 100644 index 7d92747e063e..000000000000 --- a/packages/libuild/libuild-plugin-svgr/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "@modern-js/tsconfig/base", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "declaration": true - }, - "include": ["src"], - "exclude": ["node_modules"] -} diff --git a/packages/libuild/libuild-plugin-swc/.eslintrc.cjs b/packages/libuild/libuild-plugin-swc/.eslintrc.cjs deleted file mode 100644 index df9b70bd13eb..000000000000 --- a/packages/libuild/libuild-plugin-swc/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - extends: ['@modern-js/eslint-config'], - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, -}; diff --git a/packages/libuild/libuild-plugin-swc/CHANGELOG.md b/packages/libuild/libuild-plugin-swc/CHANGELOG.md deleted file mode 100644 index 000f981001d5..000000000000 --- a/packages/libuild/libuild-plugin-swc/CHANGELOG.md +++ /dev/null @@ -1,50 +0,0 @@ -# @modern-js/libuild-plugin-swc - -## 2.35.1 - -### Patch Changes - -- a45cc5b: fix(swc): update binding to reduce package size -- 14b0906: fix(swc): fix transform core-js-pure incorrectly, allow using new decorator for js - fix(swc): 修复误转换 core-js-pure,对 js 允许使用新 decorator - -## 2.35.0 - -## 2.34.0 - -## 2.33.1 - -## 2.33.0 - -## 2.32.1 - -### Patch Changes - -- 6fc113b: chore(plugin-swc): bump swc-plugins - - chore(plugin-swc): 升级 swc-plugins - -## 2.32.0 - -### Minor Changes - -- 8d22b87: feat: add lodash option to enable or disbale lodash feature - feat: 添加 lodash 配置来打开或关闭 lodash 功能 - -## 2.31.2 - -## 2.31.1 - -## 2.31.0 - -## 2.30.0 - -### Patch Changes - -- 7cb7b24: chore(libuild): bump typescript v5 and some other devDependencies - - chore(libuild): 升级 typescript v5 和其他 devDependencies - -- 3e67a4e: chore(libuild): remove some unused dev dependencies - - chore(libuild): 移除一些无用的 dev dependencies diff --git a/packages/libuild/libuild-plugin-swc/package.json b/packages/libuild/libuild-plugin-swc/package.json deleted file mode 100644 index 6a3a8680c671..000000000000 --- a/packages/libuild/libuild-plugin-swc/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@modern-js/libuild-plugin-swc", - "version": "2.35.1", - "description": "A plugin for libuild to transform your code with swc", - "keywords": [ - "libuild", - "swc" - ], - "repository": "modern-js-dev/libuild", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "tsc && node -r tsm scripts/build.ts" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "typescript": "^5", - "tsm": "2.3.0", - "@modern-js/libuild": "workspace:*", - "@modern-js/libuild-utils": "workspace:*" - }, - "dependencies": { - "@modern-js/swc-plugins": "0.6.4", - "chalk": "4.1.0" - }, - "files": [ - "dist", - "!dist/*.map" - ] -} diff --git a/packages/libuild/libuild-plugin-swc/scripts/build.ts b/packages/libuild/libuild-plugin-swc/scripts/build.ts deleted file mode 100644 index 740dffc2d300..000000000000 --- a/packages/libuild/libuild-plugin-swc/scripts/build.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Libuilder } from '@modern-js/libuild'; - -Libuilder.run({ - format: 'cjs', - target: 'es2019', - external: ['@modern-js/swc-plugins', 'chalk'] -}); diff --git a/packages/libuild/libuild-plugin-swc/src/constants.ts b/packages/libuild/libuild-plugin-swc/src/constants.ts deleted file mode 100644 index 86d21cb21ed9..000000000000 --- a/packages/libuild/libuild-plugin-swc/src/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const swcTransformPluginName = 'libuild:swc-transform'; -export const umdPluginName = 'libuild:swc-umd'; -export const es5PluginName = 'libuild:swc-es5'; diff --git a/packages/libuild/libuild-plugin-swc/src/es5.ts b/packages/libuild/libuild-plugin-swc/src/es5.ts deleted file mode 100644 index 58498c0cb9e3..000000000000 --- a/packages/libuild/libuild-plugin-swc/src/es5.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { LibuildPlugin } from '@modern-js/libuild'; -import { Compiler } from '@modern-js/swc-plugins'; -import { es5PluginName as pluginName } from './constants'; - -export const es5Plugin = (filename?: string | ((filename: string) => string)): LibuildPlugin => { - return { - name: pluginName, - apply(compiler) { - compiler.hooks.processAsset.tapPromise({ name: pluginName }, async (chunk) => { - if (chunk.fileName.endsWith('.js') && chunk.type === 'chunk') { - const name = typeof filename === 'function' ? filename(chunk.fileName) : filename ?? chunk.fileName; - const swcCompiler = new Compiler({ - filename: name, - sourceMaps: Boolean(compiler.config.sourceMap), - inputSourceMap: false, - swcrc: false, - configFile: false, - extensions: {}, - jsc: { target: 'es5', parser: { syntax: 'ecmascript' } }, - isModule: 'unknown', - }); - const result = await swcCompiler.transformSync(name, chunk.contents.toString()); - return { - ...chunk, - contents: result.code, - map: typeof result.map === 'string' ? JSON.parse(result.map) : result.map, - }; - } - return chunk; - }); - }, - }; -}; diff --git a/packages/libuild/libuild-plugin-swc/src/index.ts b/packages/libuild/libuild-plugin-swc/src/index.ts deleted file mode 100644 index 0cbef655cbe6..000000000000 --- a/packages/libuild/libuild-plugin-swc/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { umdPlugin } from './umd'; -export { swcTransformPlugin } from './transform'; -export { es5Plugin } from './es5'; -export * from '@modern-js/swc-plugins'; -export * from './constants'; - -export { transformPlugin } from './legacy'; diff --git a/packages/libuild/libuild-plugin-swc/src/legacy.ts b/packages/libuild/libuild-plugin-swc/src/legacy.ts deleted file mode 100644 index 27be6ce8f80f..000000000000 --- a/packages/libuild/libuild-plugin-swc/src/legacy.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { LibuildPlugin } from '@modern-js/libuild'; -import { Compiler, TransformConfig } from '@modern-js/swc-plugins'; -import { - isJsExt, - resolvePathAndQuery, - isJsLoader, - deepMerge, - isTsExt, - isTsLoader, -} from '@modern-js/libuild-utils'; - -/** @deprecated */ -export const transformPlugin = (options?: TransformConfig): LibuildPlugin => { - const pluginName = 'libuild:swc-transform-legacy'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.transform.tapPromise({ name: pluginName }, async args => { - const { originalFilePath } = resolvePathAndQuery(args.path); - const isTs = isTsExt(originalFilePath) || isTsLoader(args.loader); - if (isJsExt(originalFilePath) || isJsLoader(args.loader)) { - const mergeOptions: TransformConfig = deepMerge( - { - filename: originalFilePath, - sourceMaps: Boolean(compiler.config.sourceMap), - inputSourceMap: false, - swcrc: false, - configFile: false, - jsc: { - parser: isTs - ? { - syntax: 'typescript', - tsx: true, - decorators: true, - } - : { - syntax: 'ecmascript', - jsx: true, - decorators: true, - }, - target: 'es2022', - }, - isModule: 'unknown', - extensions: {}, - }, - options || {}, - ); - const swcCompiler = new Compiler(mergeOptions); - const result = await swcCompiler.transformSync( - originalFilePath, - args.code, - ); - return { - ...args, - code: result.code, - map: - typeof result.map === 'string' - ? JSON.parse(result.map) - : result.map, - }; - } - return args; - }); - }, - }; -}; diff --git a/packages/libuild/libuild-plugin-swc/src/transform.ts b/packages/libuild/libuild-plugin-swc/src/transform.ts deleted file mode 100644 index 4ea77d2c7e50..000000000000 --- a/packages/libuild/libuild-plugin-swc/src/transform.ts +++ /dev/null @@ -1,134 +0,0 @@ -import type { TransformConfig, ImportItem } from '@modern-js/swc-plugins'; -import type { LibuildPlugin, Source } from '@modern-js/libuild'; -import { Compiler } from '@modern-js/swc-plugins'; -import { - resolvePathAndQuery, - isJsExt, - isJsLoader, - isTsExt, - isTsLoader, -} from '@modern-js/libuild-utils'; -import { getSwcTarget, getModuleConfig } from './utils'; -import { swcTransformPluginName as pluginName } from './constants'; - -// libuild-plugin-swc options -export interface SwcTransformOptions { - emitDecoratorMetadata?: boolean; - // https://www.typescriptlang.org/tsconfig#useDefineForClassFields - useDefineForClassFields?: boolean; - externalHelpers?: boolean; - pluginImport?: ImportItem[]; - transformLodash?: boolean; -} - -export const swcTransformPlugin = ( - options: SwcTransformOptions = {}, - // swcCompilerOptions?: TransformConfig -): LibuildPlugin => { - return { - name: pluginName, - apply(compiler) { - compiler.hooks.transform.tapPromise( - pluginName, - async (source): Promise => { - const { originalFilePath } = resolvePathAndQuery(source.path); - const { - emitDecoratorMetadata = false, - externalHelpers = false, - pluginImport = [], - transformLodash = false, - useDefineForClassFields, - } = options; - // Todo: emitDecoratorMetadata default value - const isTs = isTsLoader(source.loader) || isTsExt(originalFilePath); - const appDirectory = compiler.config.root; - const enableJsx = - source.loader === 'tsx' || - source.loader === 'jsx' || - /\.tsx$|\.jsx$/i.test(originalFilePath); - - // format is umd, disable swc-transform - if (compiler.config.format === 'umd') { - return source; - } - if (isJsExt(originalFilePath) || isJsLoader(source.loader)) { - const { target, format, jsx } = compiler.config; - const module = getModuleConfig(format); - - const swcCompilerOptions: TransformConfig = { - filename: originalFilePath, - sourceMaps: Boolean(compiler.config.sourceMap), - inputSourceMap: false, - swcrc: false, - configFile: false, - jsc: { - parser: isTs - ? { - syntax: 'typescript', - tsx: enableJsx, - decorators: true, - } - : { - syntax: 'ecmascript', - jsx: enableJsx, - decorators: true, - }, - transform: { - react: { - runtime: jsx === 'transform' ? 'classic' : 'automatic', - }, - useDefineForClassFields, - }, - externalHelpers, - target: getSwcTarget(target), - }, - isModule: 'unknown', - module, - extensions: { - pluginImport, - lodash: transformLodash - ? { - cwd: appDirectory, - ids: ['lodash', 'lodash-es'], - } - : undefined, - }, - // extensions: - // bundle && injectHelperToDist - // ? { - // lockCorejsVersion: { - // corejs: 'core-js', - // swcHelpers: SWC_HELPERS_DIR_PATH, - // }, - // } - // : {}, - }; - - if (emitDecoratorMetadata) { - swcCompilerOptions.jsc!.transform = { - ...swcCompilerOptions.jsc!.transform, - legacyDecorator: true, - decoratorMetadata: true, - }; - } - - const swcCompiler = new Compiler(swcCompilerOptions); - const result = await swcCompiler.transform( - originalFilePath, - source.code, - ); - return { - ...source, - code: result.code, - map: - typeof result.map === 'string' - ? JSON.parse(result.map) - : result.map, - }; - } - return source; - }, - ); - }, - }; -}; diff --git a/packages/libuild/libuild-plugin-swc/src/umd.ts b/packages/libuild/libuild-plugin-swc/src/umd.ts deleted file mode 100644 index 834588269b68..000000000000 --- a/packages/libuild/libuild-plugin-swc/src/umd.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { LibuildPlugin } from '@modern-js/libuild'; -import { Compiler } from '@modern-js/swc-plugins'; -import chalk from 'chalk'; -import { getSwcTarget } from './utils'; -import { umdPluginName as pluginName } from './constants'; - -export const umdPlugin = (filename?: string | ((filename: string) => string)): LibuildPlugin => { - return { - name: pluginName, - apply(compiler) { - // check bundle value - compiler.hooks.initialize.tap(pluginName, () => { - if (compiler.config.format === 'umd' && !compiler.config.bundle) { - console.warn(chalk.yellowBright(`The ${pluginName} plugin is only work in bundle!`)); - } - }); - - compiler.hooks.processAsset.tapPromise({ name: pluginName }, async (chunk) => { - if ( - compiler.config.format === 'umd' && - compiler.config.bundle && - chunk.fileName.endsWith('.js') && - chunk.type === 'chunk' - ) { - const name = typeof filename === 'function' ? filename(chunk.fileName) : filename ?? chunk.fileName; - const swcCompiler = new Compiler({ - filename: name, - sourceMaps: Boolean(compiler.config.sourceMap), - inputSourceMap: false, - swcrc: false, - configFile: false, - extensions: {}, - // transform by user-target - jsc: { target: getSwcTarget(compiler.config.target), parser: { syntax: 'ecmascript' } }, - module: { - type: 'umd', - }, - isModule: 'unknown', - }); - const result = await swcCompiler.transformSync(name, chunk.contents.toString()); - return { - ...chunk, - contents: result.code, - map: typeof result.map === 'string' ? JSON.parse(result.map) : result.map, - }; - } - return chunk; - }); - }, - }; -}; diff --git a/packages/libuild/libuild-plugin-swc/src/utils.ts b/packages/libuild/libuild-plugin-swc/src/utils.ts deleted file mode 100644 index 1c85d871fcfc..000000000000 --- a/packages/libuild/libuild-plugin-swc/src/utils.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { JscTarget, ModuleConfig } from '@modern-js/swc-plugins'; - -export const getSwcTarget = (target: string): JscTarget => { - // refer to JscTarget - const list = ['es3', 'es5', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'es2022']; - if (list.includes(target)) { - return target as JscTarget; - } - - if (target === 'next') { - return 'es2022'; - } - - if (target === 'es6') { - return 'es2015'; - } - - return 'es2022'; -}; - -export const getModuleConfig = (format: 'esm' | 'cjs' | 'iife'): ModuleConfig | undefined => { - if (format === 'cjs') { - return { - type: 'commonjs', - // Although swc can output `0 && module.exports = xxx` code, esbuild will remove it - // importInterop: 'node', - }; - } - - if (format === 'esm') { - return { type: 'es6' }; - } - - return undefined; -}; diff --git a/packages/libuild/libuild-plugin-swc/tsconfig.json b/packages/libuild/libuild-plugin-swc/tsconfig.json deleted file mode 100644 index 9c23f8201050..000000000000 --- a/packages/libuild/libuild-plugin-swc/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@modern-js/tsconfig/base", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "emitDeclarationOnly": true, - "declaration": true - }, - "include": ["src"], - "exclude": ["node_modules"] -} diff --git a/packages/libuild/libuild-utils/.eslintrc.cjs b/packages/libuild/libuild-utils/.eslintrc.cjs deleted file mode 100644 index 3041232d1716..000000000000 --- a/packages/libuild/libuild-utils/.eslintrc.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['@modern-js/eslint-config'], -}; diff --git a/packages/libuild/libuild-utils/.gitignore b/packages/libuild/libuild-utils/.gitignore deleted file mode 100644 index bbc71f3be643..000000000000 --- a/packages/libuild/libuild-utils/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -lib/ -esm/ \ No newline at end of file diff --git a/packages/libuild/libuild-utils/.mocharc.js b/packages/libuild/libuild-utils/.mocharc.js deleted file mode 100644 index 7cb2fb358eb0..000000000000 --- a/packages/libuild/libuild-utils/.mocharc.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); - -module.exports = { - require: require.resolve('tsm'), - extensions: ['.ts', '.tsx', '.js', '.jsx'], - spec: [path.join(__dirname, 'test/*.{spec,test}.*')], -}; diff --git a/packages/libuild/libuild-utils/CHANGELOG.md b/packages/libuild/libuild-utils/CHANGELOG.md deleted file mode 100644 index 03941d5a12a0..000000000000 --- a/packages/libuild/libuild-utils/CHANGELOG.md +++ /dev/null @@ -1,17 +0,0 @@ -# @modern-js/libuild-utils - -## 2.35.1 - -## 2.35.0 - -## 2.34.0 - -## 2.33.1 - -## 2.33.0 - -## 2.32.1 - -## 2.32.0 - -## 2.31.2 diff --git a/packages/libuild/libuild-utils/package.json b/packages/libuild/libuild-utils/package.json deleted file mode 100644 index 52fb8d2c7c5e..000000000000 --- a/packages/libuild/libuild-utils/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@modern-js/libuild-utils", - "version": "2.35.1", - "description": "utils for libuild", - "license": "MIT", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "source": "./src/index.ts", - "files": [ - "dist" - ], - "scripts": { - "test": "mocha", - "build": "tsc -p tsconfig.build.json" - }, - "devDependencies": { - "@types/chai": "4.2.22", - "@types/node": "12.20.42", - "@types/mocha": "9.0.0", - "chai": "4.3.4", - "mocha": "9.1.3", - "typescript": "^5" - } -} diff --git a/packages/libuild/libuild-utils/src/assert.ts b/packages/libuild/libuild-utils/src/assert.ts deleted file mode 100644 index 4b01b858eac1..000000000000 --- a/packages/libuild/libuild-utils/src/assert.ts +++ /dev/null @@ -1,19 +0,0 @@ -export function isEmpty(value: T | null | undefined): value is null { - return value == null; -} - -export function isDef(x: T): x is NonNullable { - return x !== undefined && x !== null; -} - -export function isObject(value: any): value is Record { - return Object.prototype.toString.call(value) === '[object Object]'; -} - -export function isEmptyObject(value: any): value is Record { - if (!isObject(value)) { - return false; - } - const keys = Object.keys(value); - return keys.length === 0; -} diff --git a/packages/libuild/libuild-utils/src/deepMerge.ts b/packages/libuild/libuild-utils/src/deepMerge.ts deleted file mode 100644 index 2e11a0071da8..000000000000 --- a/packages/libuild/libuild-utils/src/deepMerge.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { isObject } from './assert'; - -export function deepMerge(lower: Record, higher: Record) { - if (arguments.length !== 2 || !isObject(lower) || !isObject(higher)) { - throw Error(`${lower} and ${higher} must be Object`); - } - const merged = { ...lower }; - for (const key in higher) { - const value = higher[key]; - if (value == null) { - continue; - } - const existing = merged[key]; - if (Array.isArray(existing) && Array.isArray(value)) { - merged[key] = [...existing, ...value]; - } else if (isObject(existing) && isObject(value)) { - merged[key] = deepMerge(existing, value); - } else { - merged[key] = value; - } - } - return merged; -} diff --git a/packages/libuild/libuild-utils/src/index.ts b/packages/libuild/libuild-utils/src/index.ts deleted file mode 100644 index b283f388df02..000000000000 --- a/packages/libuild/libuild-utils/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './assert'; -export * from './deepMerge'; -export * from './resolvePathAndQuery'; diff --git a/packages/libuild/libuild-utils/src/resolvePathAndQuery.ts b/packages/libuild/libuild-utils/src/resolvePathAndQuery.ts deleted file mode 100644 index 057d6dc18cf7..000000000000 --- a/packages/libuild/libuild-utils/src/resolvePathAndQuery.ts +++ /dev/null @@ -1,45 +0,0 @@ -import qs from 'querystring'; -export type Query = Record; - -interface ResolveResult { - originalFilePath: string; - rawQuery?: string; - query: Query; -} - -export const resolvePathAndQuery = (originalPath: string): ResolveResult => { - const [filePath, queryStr] = originalPath.split('?'); - const query = qs.parse(queryStr ?? '') as Query; - - for (const key of Object.keys(query)) { - if (query[key] === '') { - query[key] = true; - } - } - - return { - query, - rawQuery: queryStr, - originalFilePath: filePath, - }; -}; - -export function isStyleExt(path: string) { - return /\.(c|le|sa|sc)ss(\?.*)?$/.test(path); -} - -export function isJsExt(path: string) { - return /\.(m|c)?(j|t)sx?(\?.*)?$/.test(path); -} - -export function isJsLoader(loader?: string) { - return loader === 'js' || loader === 'ts' || loader === 'tsx' || loader === 'jsx'; -} - -export function isTsExt(path: string) { - return /\.(m|c)?tsx?(\?.*)?$/.test(path); -} - -export function isTsLoader(loader?: string) { - return loader === 'ts' || loader === 'tsx'; -} diff --git a/packages/libuild/libuild-utils/test/assert.test.ts b/packages/libuild/libuild-utils/test/assert.test.ts deleted file mode 100644 index b801c03b9da8..000000000000 --- a/packages/libuild/libuild-utils/test/assert.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { expect } from 'chai'; -import { isEmpty, isObject, isDef, isEmptyObject } from '../src'; - -describe('isEmpty', () => { - it('false', () => { - expect(isEmpty('')).to.be.false; - expect(isEmpty(1)).to.be.false; - expect(isEmpty([])).to.be.false; - expect(isEmpty(BigInt(1))).to.be.false; - expect(isEmpty(new Set())).to.be.false; - expect(isEmpty(new Map())).to.be.false; - expect(isEmpty({})).to.be.false; - expect(isEmpty(new Object())).to.be.false; - }); - - it('true', () => { - expect(isEmpty(null)).to.be.true; - expect(isEmpty(undefined)).to.be.true; - }); -}); - -describe('isDef', () => { - it('true', () => { - expect(isDef('')).to.be.true; - expect(isDef(1)).to.be.true; - expect(isDef([])).to.be.true; - expect(isDef(BigInt(1))).to.be.true; - expect(isDef(new Set())).to.be.true; - expect(isDef(new Map())).to.be.true; - expect(isDef({})).to.be.true; - expect(isDef(new Object())).to.be.true; - }); - - it('false', () => { - expect(isDef(null)).to.be.false; - expect(isDef(undefined)).to.be.false; - }); -}); - -describe('isObject', () => { - it('not object', () => { - expect(isObject('')).to.be.false; - expect(isObject(1)).to.be.false; - expect(isObject([])).to.be.false; - expect(isObject(BigInt(1))).to.be.false; - expect(isObject(new Set())).to.be.false; - expect(isObject(new Map())).to.be.false; - }); - - it('is object', () => { - expect(isObject({})).to.be.true; - expect(isObject(new Object())).to.be.true; - }); -}); - -describe('isEmptyObject', () => { - it('not emptyObject', () => { - expect(isEmptyObject('')).to.be.false; - expect(isEmptyObject(1)).to.be.false; - expect(isEmptyObject([])).to.be.false; - expect(isEmptyObject(BigInt(1))).to.be.false; - expect(isEmptyObject(new Set())).to.be.false; - expect(isEmptyObject(new Map())).to.be.false; - expect(isEmptyObject({ name: 'foo' })).to.be.false; - }); - - it('is emptyObject', () => { - expect(isObject({})).to.be.true; - expect(isObject(new Object())).to.be.true; - }); -}); diff --git a/packages/libuild/libuild-utils/test/deepMerge.test.ts b/packages/libuild/libuild-utils/test/deepMerge.test.ts deleted file mode 100644 index 212ae44da6db..000000000000 --- a/packages/libuild/libuild-utils/test/deepMerge.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { expect } from 'chai'; -import { deepMerge } from '../src'; - -describe('deepMerge', () => { - it('args are not Object', () => { - // @ts-ignore - expect(() => deepMerge(1, {})).Throw(Error); - // @ts-ignore - expect(() => deepMerge({}, false)).Throw(Error); - expect(() => deepMerge([], {})).Throw(Error); - }); - - it('different', () => { - expect(deepMerge({ a: 1 }, { b: '2' })).deep.equal({ a: 1, b: '2' }); - }); - - it('second has higher priortesty', () => { - expect(deepMerge({ a: 1, b: 2 }, { b: '2' })).deep.equal({ a: 1, b: '2' }); - }); - - it('`undefined` or `null` will no cover', () => { - expect(deepMerge({ a: 1, b: 2 }, { a: undefined, b: '2', c: null })).deep.equal({ a: 1, b: '2' }); - }); - - it('do not mutate inputs', () => { - const x = { a: { b: 1 }, c: 2 }; - const y = { d: 1, c: '2', g: {}, e: [] }; - deepMerge(x, y); - expect(x).deep.equal({ a: { b: 1 }, c: 2 }); - expect(y).deep.equal({ d: 1, c: '2', g: {}, e: [] }); - }); - - it('deep clone', () => { - expect(deepMerge({}, { a: { b: { c: [1] } } })).deep.equal({ a: { b: { c: [1] } } }); - }); - - it('deep replace and merge', () => { - expect(deepMerge({ a: { b: 1, c: 2 } }, { a: { b: {}, d: [] } })).deep.equal({ a: { b: {}, c: 2, d: [] } }); - }); - - it('deep array', () => { - expect(deepMerge({ a: [1], b: { a: [1] }, c: [1, {}] }, { a: 1, b: { a: [2] }, c: [2] })).deep.equal({ - a: 1, - b: { a: [1, 2] }, - c: [1, {}, 2], - }); - }); -}); diff --git a/packages/libuild/libuild-utils/test/resolvePathAndQuery.test.ts b/packages/libuild/libuild-utils/test/resolvePathAndQuery.test.ts deleted file mode 100644 index 656797c64081..000000000000 --- a/packages/libuild/libuild-utils/test/resolvePathAndQuery.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { expect } from 'chai'; -import { isJsExt, isJsLoader, resolvePathAndQuery } from '../src'; - -describe('resolvePathAndQuery', () => { - it('basic', () => { - expect(resolvePathAndQuery('a')).deep.equal({ query: {}, rawQuery: undefined, originalFilePath: 'a' }); - expect(resolvePathAndQuery('a = 1')).deep.equal({ query: {}, rawQuery: undefined, originalFilePath: 'a = 1' }); - expect(resolvePathAndQuery('')).deep.equal({ query: {}, rawQuery: undefined, originalFilePath: '' }); - expect(resolvePathAndQuery('a?b=1&c&d=2')).deep.equal({ - query: { b: '1', c: true, d: '2' }, - rawQuery: 'b=1&c&d=2', - originalFilePath: 'a', - }); - }); - - it('isJsExt', () => { - expect(isJsExt('a.js')).to.be.true; - expect(isJsExt('a.mjs')).to.be.true; - expect(isJsExt('a.cjs')).to.be.true; - expect(isJsExt('a.js?a=b')).to.be.true; - expect(isJsExt('a.ts')).to.be.true; - expect(isJsExt('a.ts?a=b')).to.be.true; - expect(isJsExt('a.tsx')).to.be.true; - expect(isJsExt('a.tsx?a=b')).to.be.true; - expect(isJsExt('a.vue')).to.be.false; - expect(isJsExt('a.vue?a=b')).to.be.false; - }); - - it('isJsLoader', () => { - expect(isJsLoader('ts')).to.be.true; - expect(isJsLoader('tsx')).to.be.true; - expect(isJsLoader('js')).to.be.true; - expect(isJsLoader('jsx')).to.be.true; - expect(isJsLoader()).to.be.false; - }); -}); diff --git a/packages/libuild/libuild-utils/tsconfig.build.json b/packages/libuild/libuild-utils/tsconfig.build.json deleted file mode 100644 index 9cc88c2872e0..000000000000 --- a/packages/libuild/libuild-utils/tsconfig.build.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src"], - "compilerOptions": { - "rootDir": "src" - } -} diff --git a/packages/libuild/libuild-utils/tsconfig.json b/packages/libuild/libuild-utils/tsconfig.json deleted file mode 100644 index 9a3eff3415df..000000000000 --- a/packages/libuild/libuild-utils/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "@modern-js/tsconfig/base", - "compilerOptions": { - "baseUrl": "src", - "outDir": "dist", - "rootDir": ".", - "module": "CommonJS", - "types": ["mocha", "node"], - "declaration": true, - "target": "ES2019" - }, - "include": ["src", "test"] -} diff --git a/packages/module/plugin-module-babel/package.json b/packages/module/plugin-module-babel/package.json index a526e385f183..51f3bd2adcb2 100644 --- a/packages/module/plugin-module-babel/package.json +++ b/packages/module/plugin-module-babel/package.json @@ -1,6 +1,13 @@ { "name": "@modern-js/plugin-module-babel", - "description": "The babel plugin of Modern.js Module ols.", + "version": "2.35.1", + "description": "The babel plugin of Modern.js Module", + "keywords": [ + "react", + "framework", + "modern", + "modern.js" + ], "homepage": "https://modernjs.dev/module-tools", "bugs": "https://github.com/web-infra-dev/modern.js/issues", "repository": { @@ -9,42 +16,36 @@ "directory": "packages/module/plugin-module-babel" }, "license": "MIT", - "keywords": [ - "react", - "framework", - "modern", - "modern.js" - ], - "version": "2.35.1", - "types": "./src/index.ts", + "sideEffects": false, "main": "./dist/index.js", + "types": "./src/index.ts", "scripts": { - "prepublishOnly": "only-allow-pnpm", - "dev": "mdn build --watch", "build": "mdn build", + "dev": "mdn build --watch", + "prepublishOnly": "only-allow-pnpm", "test": "jest --passWithNoTests" }, "dependencies": { - "@modern-js/libuild-plugin-babel": "workspace:*", + "@babel/core": "^7.22.5", "@swc/helpers": "0.5.1" }, "devDependencies": { + "@modern-js/module-tools": "workspace:*", + "@scripts/build": "workspace:*", + "@scripts/jest-config": "workspace:*", + "@types/babel__core": "7.1.16", "@types/jest": "^29", "@types/node": "^14", - "typescript": "^5", - "@scripts/build": "workspace:*", "jest": "^29", - "@scripts/jest-config": "workspace:*", - "@modern-js/module-tools": "workspace:*" + "typescript": "^5" }, "peerDependencies": { "@modern-js/module-tools": "workspace:^2.35.1" }, - "sideEffects": false, "publishConfig": { - "registry": "https://registry.npmjs.org/", "access": "public", "provenance": true, + "registry": "https://registry.npmjs.org/", "types": "./dist/index.d.ts" } } diff --git a/packages/module/plugin-module-babel/src/index.ts b/packages/module/plugin-module-babel/src/index.ts index 77cb8dc47431..56118cea2230 100644 --- a/packages/module/plugin-module-babel/src/index.ts +++ b/packages/module/plugin-module-babel/src/index.ts @@ -1,22 +1,57 @@ -import { CliPlugin, ModuleTools } from '@modern-js/module-tools'; -import { babelPlugin } from '@modern-js/libuild-plugin-babel'; +import type { TransformOptions as BabelTransformOptions } from '@babel/core'; +import { + CliPlugin, + ICompiler, + ModuleTools, + isJsExt, + isJsLoader, +} from '@modern-js/module-tools'; -export type Options = typeof babelPlugin extends (arg1: infer P) => void - ? P - : never; +const name = 'babel'; -// deprecated named export -export const ModulePluginBabel = ( - options?: Options, +export const getBabelHook = (options?: BabelTransformOptions) => ({ + name, + apply(compiler: ICompiler) { + compiler.hooks.transform.tapPromise({ name }, async args => { + if (isJsExt(args.path) || isJsLoader(args.loader)) { + const result = await require('@babel/core').transformAsync(args.code, { + filename: args.path, + sourceFileName: args.path, + sourceMaps: Boolean(compiler.config.sourceMap), + sourceType: 'unambiguous', + inputSourceMap: false, + babelrc: false, + configFile: false, + compact: false, + exclude: [/\bcore-js\b/], + ...options, + }); + return { + ...args, + code: result?.code, + map: result?.map, + }; + } + return args; + }); + }, +}); + +export const modulePluginBabel = ( + options?: BabelTransformOptions, ): CliPlugin => ({ name: 'babel-plugin', setup: () => ({ - modifyLibuild(config) { - config.plugins?.unshift(babelPlugin(options ?? {})); + beforeBuildTask(config) { + const hook = getBabelHook(options); + config.hooks.push(hook); return config; }, }), }); -// right named export -export { ModulePluginBabel as modulePluginBabel }; +/** + * deprecated named export, use modulePluginBabel instead. + * @deprecated + */ +export const ModulePluginBabel = modulePluginBabel; diff --git a/packages/module/plugin-module-banner/package.json b/packages/module/plugin-module-banner/package.json index 9fdd619d7061..6ac76279c42b 100644 --- a/packages/module/plugin-module-banner/package.json +++ b/packages/module/plugin-module-banner/package.json @@ -1,6 +1,13 @@ { "name": "@modern-js/plugin-module-banner", + "version": "2.35.1", "description": "The banner plugin of Modern.js Module.", + "keywords": [ + "react", + "framework", + "modern", + "modern.js" + ], "homepage": "https://modernjs.dev/module-tools", "bugs": "https://github.com/modern-js-dev/modern.js/issues", "repository": { @@ -9,15 +16,6 @@ "directory": "packages/module/plugin-module-banner" }, "license": "MIT", - "keywords": [ - "react", - "framework", - "modern", - "modern.js" - ], - "version": "2.35.1", - "types": "./src/index.ts", - "main": "./dist/index.js", "exports": { ".": { "node": { @@ -26,22 +24,26 @@ } } }, + "main": "./dist/index.js", + "types": "./src/index.ts", "scripts": { - "prepublishOnly": "only-allow-pnpm", - "dev": "mdn build --watch", "build": "mdn build", + "dev": "mdn build --watch", + "prepublishOnly": "only-allow-pnpm", "test": "jest --passWithNoTests" }, + "dependencies": { + "@swc/helpers": "0.5.1" + }, "devDependencies": { - "@types/jest": "^29", - "@types/node": "^14", - "typescript": "^5", - "jest": "^29", + "@modern-js/module-tools": "workspace:*", "@scripts/build": "workspace:*", "@scripts/jest-config": "workspace:*", "@swc/helpers": "0.5.1", - "@modern-js/module-tools": "workspace:*", - "@modern-js/libuild": "workspace:*" + "@types/jest": "^29", + "@types/node": "^14", + "jest": "^29", + "typescript": "^5" }, "peerDependencies": { "@modern-js/module-tools": "workspace:^2.35.1" @@ -51,13 +53,10 @@ "optional": true } }, - "dependencies": { - "@swc/helpers": "0.5.1" - }, "publishConfig": { - "registry": "https://registry.npmjs.org/", "access": "public", "provenance": true, + "registry": "https://registry.npmjs.org/", "types": "./dist/index.d.ts" } } diff --git a/packages/module/plugin-module-banner/src/index.ts b/packages/module/plugin-module-banner/src/index.ts index 2462610094cc..1cf5490f06a8 100644 --- a/packages/module/plugin-module-banner/src/index.ts +++ b/packages/module/plugin-module-banner/src/index.ts @@ -1,12 +1,16 @@ import type { CliPlugin, ModuleTools } from '@modern-js/module-tools'; +/** + * @deprecated + * use config 'banner' instead. + */ export const modulePluginBanner = (options: { banner: { js?: string; css?: string }; footer?: { js?: string; css?: string }; }): CliPlugin => ({ name: '@modern-js/plugin-module-banner', setup: () => ({ - modifyLibuild(config, next) { + beforeBuildTask(config) { const lastEsbuildOptions = config.esbuildOptions; config.esbuildOptions = c => { let lastEsbuildConfig = {}; @@ -20,7 +24,7 @@ export const modulePluginBanner = (options: { banner: options.banner, }; }; - return next(config); + return config; }, }), }); diff --git a/packages/module/plugin-module-import/package.json b/packages/module/plugin-module-import/package.json index 5c46ca935cdc..10e51d22da5a 100644 --- a/packages/module/plugin-module-import/package.json +++ b/packages/module/plugin-module-import/package.json @@ -1,6 +1,13 @@ { "name": "@modern-js/plugin-module-import", + "version": "2.35.1", "description": "The import plugin of Modern.js Module.", + "keywords": [ + "react", + "framework", + "modern", + "modern.js" + ], "homepage": "https://modernjs.dev/module-tools", "bugs": "https://github.com/modern-js-dev/modern.js/issues", "repository": { @@ -9,15 +16,6 @@ "directory": "packages/module/plugin-module-import" }, "license": "MIT", - "keywords": [ - "react", - "framework", - "modern", - "modern.js" - ], - "version": "2.35.1", - "types": "./src/index.ts", - "main": "./dist/index.js", "exports": { ".": { "node": { @@ -26,26 +24,27 @@ } } }, + "main": "./dist/index.js", + "types": "./src/index.ts", "scripts": { - "prepublishOnly": "only-allow-pnpm", - "dev": "mdn build --watch", "build": "mdn build", + "dev": "mdn build --watch", + "prepublishOnly": "only-allow-pnpm", "test": "jest --passWithNoTests" }, "dependencies": { - "@modern-js/libuild-plugin-swc": "workspace:*", + "@modern-js/swc-plugins": "0.6.0", "@swc/helpers": "0.5.1" }, "devDependencies": { - "@types/jest": "^29", - "@types/node": "^14", - "typescript": "^5", + "@modern-js/module-tools": "workspace:*", "@scripts/build": "workspace:*", - "jest": "^29", "@scripts/jest-config": "workspace:*", "@swc/helpers": "0.5.1", - "@modern-js/module-tools": "workspace:*", - "@modern-js/libuild": "workspace:*" + "@types/jest": "^29", + "@types/node": "^14", + "jest": "^29", + "typescript": "^5" }, "peerDependencies": { "@modern-js/module-tools": "workspace:^2.35.1" @@ -56,9 +55,9 @@ } }, "publishConfig": { - "registry": "https://registry.npmjs.org/", "access": "public", "provenance": true, + "registry": "https://registry.npmjs.org/", "types": "./dist/index.d.ts" } } diff --git a/packages/module/plugin-module-import/src/index.ts b/packages/module/plugin-module-import/src/index.ts index d3299aa5294e..8ae831ebfbff 100644 --- a/packages/module/plugin-module-import/src/index.ts +++ b/packages/module/plugin-module-import/src/index.ts @@ -1,47 +1,23 @@ -import type { CliPlugin, ModuleTools } from '@modern-js/module-tools'; -import type { ImportItem } from '@modern-js/libuild-plugin-swc'; -import { swcTransformPluginName } from '@modern-js/libuild-plugin-swc'; +import type { + CliPlugin, + ModuleTools, + BaseBuildConfig, +} from '@modern-js/module-tools'; +/** + * use config 'transformImport' instead. + * @deprecated + */ export const modulePluginImport = (options: { - pluginImport?: ImportItem[]; + pluginImport?: BaseBuildConfig['transformImport']; }): CliPlugin => ({ name: '@modern-js/plugin-module-import', setup: () => ({ beforeBuildTask(config) { - config.transformImport = options.pluginImport ?? []; + config.transformImport = options.pluginImport ?? config.transformImport; return config; }, - async modifyLibuild(config, next) { - // when libuild:swc-transform found - if (config.plugins?.find(p => p.name === swcTransformPluginName)) { - return next(config); - } - - if (!options.pluginImport || options.pluginImport.length === 0) { - return next(config); - } - - const { transformPlugin } = await import('@modern-js/libuild-plugin-swc'); - config.plugins?.push( - transformPlugin({ - jsc: { - // swc transform jsx to `React.createElement` in default mode. - transform: { - react: { - runtime: config.jsx === 'transform' ? 'classic' : 'automatic', - }, - }, - }, - extensions: { - pluginImport: options.pluginImport ?? [], - }, - }), - ); - - return next(config); - }, }), }); -// deprecated default export export default modulePluginImport; diff --git a/packages/module/plugin-module-main-fields/.eslintrc.js b/packages/module/plugin-module-main-fields/.eslintrc.js deleted file mode 100644 index 414a253db518..000000000000 --- a/packages/module/plugin-module-main-fields/.eslintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - root: true, - extends: ['@modern-js'], - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, -}; diff --git a/packages/module/plugin-module-main-fields/.npmignore b/packages/module/plugin-module-main-fields/.npmignore deleted file mode 100644 index 353fddf17262..000000000000 --- a/packages/module/plugin-module-main-fields/.npmignore +++ /dev/null @@ -1,31 +0,0 @@ -.DS_Store - -.pnp -.pnp.js -.env.local -.env.*.local -*.log* - -node_modules/ -*.tsbuildinfo -.eslintcache - -coverage/ -output/ -output_resource/ -tests/ - -.vscode/**/* -!.vscode/settings.json -!.vscode/extensions.json -.idea/ - -src/ - -modern.config.* -jest.config.js -.eslintrc.js -.eslintrc -tsconfig.json -CHANGELOG.md - diff --git a/packages/module/plugin-module-main-fields/CHANGELOG.md b/packages/module/plugin-module-main-fields/CHANGELOG.md deleted file mode 100644 index 49c7c1119a51..000000000000 --- a/packages/module/plugin-module-main-fields/CHANGELOG.md +++ /dev/null @@ -1,357 +0,0 @@ -# @modern-js/plugin-module-main-fields - -## 2.35.1 - -### Patch Changes - -- Updated dependencies [ce24aad] - - @modern-js/module-tools@2.35.1 - -## 2.35.0 - -### Patch Changes - -- Updated dependencies [15b834f] - - @modern-js/module-tools@2.35.0 - -## 2.34.0 - -### Patch Changes - -- Updated dependencies [76af015] - - @modern-js/module-tools@2.34.0 - -## 2.33.1 - -### Patch Changes - -- Updated dependencies [c38570e] -- Updated dependencies [7ad82bd] - - @modern-js/module-tools@2.33.1 - -## 2.33.0 - -### Patch Changes - -- @modern-js/module-tools@2.33.0 - -## 2.32.1 - -### Patch Changes - -- @modern-js/module-tools@2.32.1 - -## 2.32.0 - -### Patch Changes - -- Updated dependencies [8d22b87] - - @modern-js/module-tools@2.32.0 - -## 2.31.2 - -### Patch Changes - -- @modern-js/module-tools@2.31.2 - -## 2.31.1 - -### Patch Changes - -- @modern-js/module-tools@2.31.1 - -## 2.31.0 - -### Patch Changes - -- Updated dependencies [4c03d9a] -- Updated dependencies [1882366] - - @modern-js/module-tools@2.31.0 - -## 2.30.0 - -### Patch Changes - -- Updated dependencies [c03be09] - - @modern-js/module-tools@2.30.0 - -## 2.29.0 - -### Patch Changes - -- Updated dependencies [6993eb6] -- Updated dependencies [0f680ec] - - @modern-js/module-tools@2.29.0 - -## 2.28.0 - -### Patch Changes - -- d3e52e4: chore(CI): update build config to improve vitest CI perf - - chore(CI): 更新构建配置来提升 vitest CI 性能 - -- Updated dependencies [3092f1f] -- Updated dependencies [118c1c0] -- Updated dependencies [b7a8c43] -- Updated dependencies [d3e52e4] - - @modern-js/module-tools@2.28.0 - -## 2.27.0 - -### Patch Changes - -- @modern-js/module-tools@2.27.0 - -## 2.26.0 - -### Patch Changes - -- Updated dependencies [54c484c] -- Updated dependencies [cc2e3b7] - - @modern-js/module-tools@2.26.0 - -## 2.25.2 - -### Patch Changes - -- Updated dependencies [a2a5bcd] - - @modern-js/module-tools@2.25.2 - -## 2.25.1 - -### Patch Changes - -- Updated dependencies [273e3cd] - - @modern-js/module-tools@2.25.1 - -## 2.25.0 - -### Patch Changes - -- Updated dependencies [9aa2c25] -- Updated dependencies [d287b7f] - - @modern-js/module-tools@2.25.0 - -## 2.24.0 - -### Patch Changes - -- Updated dependencies [53ba418] -- Updated dependencies [3b82675] -- Updated dependencies [7073297] - - @modern-js/module-tools@2.24.0 - -## 2.23.1 - -### Patch Changes - -- @modern-js/module-tools@2.23.1 - -## 2.23.0 - -### Patch Changes - -- 7e6fb5f: chore: publishConfig add provenance config - - chore: publishConfig 增加 provenance 配置 - -- Updated dependencies [7e6fb5f] -- Updated dependencies [21b7f86] -- Updated dependencies [d1ef55f] - - @modern-js/module-tools@2.23.0 - -## 2.22.1 - -### Patch Changes - -- @modern-js/module-tools@2.22.1 - -## 2.22.0 - -### Patch Changes - -- ad49140: chore: adjust output and package.json fields - chore: 调整包的产物格式以及 packgae.json 里的字段 -- e2913dd: chore: update module plugin docs and readme - chore: 更新模块插件的文档和 readme -- Updated dependencies [d19dc11] -- Updated dependencies [c890980] -- Updated dependencies [4b7488c] - - @modern-js/module-tools@2.22.0 - -## 2.21.1 - -### Patch Changes - -- @modern-js/module-tools@2.21.1 - -## 2.21.0 - -### Patch Changes - -- 26dcf3a: chore: bump typescript to v5 in devDependencies - - chore: 升级 devDependencies 中的 typescript 版本到 v5 - -- Updated dependencies [df43559] -- Updated dependencies [26dcf3a] -- Updated dependencies [ad78387] - - @modern-js/module-tools@2.21.0 - -## 2.20.0 - -### Patch Changes - -- Updated dependencies [6b9d90a] -- Updated dependencies [6b9d90a] - - @modern-js/module-tools@2.20.0 - -## 2.19.1 - -### Patch Changes - -- @modern-js/module-tools@2.19.1 - -## 2.19.0 - -### Patch Changes - -- @modern-js/module-tools@2.19.0 - -## 2.18.1 - -### Patch Changes - -- Updated dependencies [cdc9db1] -- Updated dependencies [b161968] - - @modern-js/module-tools@2.18.1 - -## 2.18.0 - -### Patch Changes - -- Updated dependencies [f65d3e8] - - @modern-js/module-tools@2.18.0 - -## 2.17.1 - -### Patch Changes - -- @modern-js/module-tools@2.17.1 - -## 2.17.0 - -### Patch Changes - -- @modern-js/module-tools@2.17.0 - -## 2.16.0 - -### Patch Changes - -- 4e876ab: chore: package.json include the monorepo-relative directory - - chore: 在 package.json 中声明 monorepo 的子路径 - -- Updated dependencies [b06f571] -- Updated dependencies [acc0a00] -- Updated dependencies [fd4a8a6] -- Updated dependencies [4e876ab] -- Updated dependencies [355d36e] -- Updated dependencies [b06f571] - - @modern-js/module-tools@2.16.0 - -## 2.15.0 - -### Patch Changes - -- @modern-js/module-tools@2.15.0 - -## 2.14.0 - -### Patch Changes - -- Updated dependencies [f08f3ab] -- Updated dependencies [432ac8b] - - @modern-js/module-tools@2.14.0 - -## 2.13.4 - -### Patch Changes - -- @modern-js/module-tools@2.13.4 - -## 2.13.3 - -### Patch Changes - -- Updated dependencies [c20e67d] - - @modern-js/module-tools@2.13.3 - -## 2.13.2 - -### Patch Changes - -- @modern-js/module-tools@2.13.2 - -## 2.13.1 - -### Patch Changes - -- @modern-js/module-tools@2.13.1 - -## 2.13.0 - -### Patch Changes - -- Updated dependencies [034f36b] -- Updated dependencies [88faab3] -- Updated dependencies [034f36b] -- Updated dependencies [79bc089] - - @modern-js/module-tools@2.13.0 - -## 2.12.0 - -### Patch Changes - -- 979b15f: chore: remove to module folder - chore: 移动至 module 文件夹 -- Updated dependencies [af705fa] -- Updated dependencies [0baa168] -- Updated dependencies [1cdb379] -- Updated dependencies [3936535] -- Updated dependencies [8a3fbbd] -- Updated dependencies [8bc2d12] - - @modern-js/module-tools@2.12.0 - -## 2.11.0 - -### Patch Changes - -- Updated dependencies [aa0a312] -- Updated dependencies [6118636] -- Updated dependencies [f1b2629] - - @modern-js/module-tools@2.11.0 - -## 2.10.0 - -### Patch Changes - -- 0da32d0: chore: upgrade jest and puppeteer - chore: 升级 jest 和 puppeteer 到 latest -- Updated dependencies [0da32d0] - - @modern-js/module-tools@2.10.0 - -## 2.9.0 - -### Patch Changes - -- @modern-js/module-tools@2.9.0 - -## 2.8.0 - -### Patch Changes - -- Updated dependencies [adf68ec3ed] - - @modern-js/module-tools@2.8.0 diff --git a/packages/module/plugin-module-main-fields/LICENSE b/packages/module/plugin-module-main-fields/LICENSE deleted file mode 100644 index 39e3c5971226..000000000000 --- a/packages/module/plugin-module-main-fields/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021-present Modern.js - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/module/plugin-module-main-fields/README.md b/packages/module/plugin-module-main-fields/README.md deleted file mode 100644 index 2bf670dc78f6..000000000000 --- a/packages/module/plugin-module-main-fields/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Deprecated Package - -This package will be deprecated when next major version release and will no longer be maintained. - -In 2.x, you can still use it. diff --git a/packages/module/plugin-module-main-fields/jest.config.js b/packages/module/plugin-module-main-fields/jest.config.js deleted file mode 100644 index 5fcd3e5b28bd..000000000000 --- a/packages/module/plugin-module-main-fields/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const sharedConfig = require('@scripts/jest-config'); - -/** @type {import('@jest/types').Config.InitialOptions} */ -module.exports = { - ...sharedConfig, - rootDir: __dirname, -}; diff --git a/packages/module/plugin-module-main-fields/modern.config.js b/packages/module/plugin-module-main-fields/modern.config.js deleted file mode 100644 index c2bf3e85b393..000000000000 --- a/packages/module/plugin-module-main-fields/modern.config.js +++ /dev/null @@ -1,5 +0,0 @@ -const { tscLikeBuildConfig } = require('@scripts/build'); - -module.exports = { - buildConfig: tscLikeBuildConfig, -}; diff --git a/packages/module/plugin-module-main-fields/package.json b/packages/module/plugin-module-main-fields/package.json deleted file mode 100644 index 9c0dcc4da7ad..000000000000 --- a/packages/module/plugin-module-main-fields/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@modern-js/plugin-module-main-fields", - "description": "The main fields plugin of Modern.js Module.", - "homepage": "https://modernjs.dev/module-tools", - "bugs": "https://github.com/web-infra-dev/modern.js/issues", - "repository": { - "type": "git", - "url": "https://github.com/web-infra-dev/modern.js", - "directory": "packages/module/plugin-module-main-fields" - }, - "license": "MIT", - "keywords": [ - "react", - "framework", - "modern", - "modern.js" - ], - "version": "2.35.1", - "types": "./src/index.ts", - "main": "./dist/index.js", - "scripts": { - "prepublishOnly": "only-allow-pnpm", - "dev": "modern-lib build --watch", - "build": "modern-lib build", - "test": "jest --passWithNoTests" - }, - "devDependencies": { - "@types/jest": "^29", - "@types/node": "^14", - "typescript": "^5", - "@scripts/build": "workspace:*", - "jest": "^29", - "@scripts/jest-config": "workspace:*", - "@swc/helpers": "0.5.1", - "@modern-js/module-tools": "workspace:*" - }, - "peerDependencies": { - "@modern-js/module-tools": "workspace:^2.35.1" - }, - "sideEffects": false, - "publishConfig": { - "registry": "https://registry.npmjs.org/", - "access": "public", - "provenance": true, - "types": "./dist/index.d.ts" - } -} diff --git a/packages/module/plugin-module-main-fields/src/index.ts b/packages/module/plugin-module-main-fields/src/index.ts deleted file mode 100644 index f70326e05ddd..000000000000 --- a/packages/module/plugin-module-main-fields/src/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { CliPlugin, ModuleTools } from '@modern-js/module-tools'; - -export const ModuleMainFieldsPlugin = (options: { - mainFields: string[]; - disableMerge?: boolean; -}): CliPlugin => ({ - name: 'module-main-fields', - setup: () => ({ - modifyLibuild(config) { - if (config.resolve) { - config.resolve.mainFields = options.disableMerge - ? options.mainFields - : { - ...(config.resolve.mainFields ?? {}), - ...options.mainFields, - }; - } else { - config.resolve = { - mainFields: options.mainFields, - }; - } - - return config; - }, - }), -}); diff --git a/packages/module/plugin-module-main-fields/tsconfig.json b/packages/module/plugin-module-main-fields/tsconfig.json deleted file mode 100644 index e02117a9771c..000000000000 --- a/packages/module/plugin-module-main-fields/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@modern-js/tsconfig/base", - "compilerOptions": { - "declaration": false, - "jsx": "preserve", - "baseUrl": "./", - "isolatedModules": true, - "paths": {} - }, - "include": ["src"] -} diff --git a/packages/module/plugin-module-node-polyfill/package.json b/packages/module/plugin-module-node-polyfill/package.json index f5a2c80d11ea..e077a66d6841 100644 --- a/packages/module/plugin-module-node-polyfill/package.json +++ b/packages/module/plugin-module-node-polyfill/package.json @@ -1,6 +1,13 @@ { "name": "@modern-js/plugin-module-node-polyfill", - "description": "The node polyfill plugin of Modern.js Module.", + "version": "2.35.1", + "description": "The node polyfill plugin of Modern.js Module", + "keywords": [ + "react", + "framework", + "modern", + "modern.js" + ], "homepage": "https://modernjs.dev/module-tools", "bugs": "https://github.com/web-infra-dev/modern.js/issues", "repository": { @@ -9,30 +16,46 @@ "directory": "packages/module/plugin-module-node-polyfill" }, "license": "MIT", - "keywords": [ - "react", - "framework", - "modern", - "modern.js" - ], - "version": "2.35.1", - "types": "./src/index.ts", "main": "./dist/index.js", + "types": "./src/index.ts", "scripts": { - "prepublishOnly": "only-allow-pnpm", - "dev": "mdn build --watch", "build": "mdn build", + "dev": "mdn build --watch", + "prepublishOnly": "only-allow-pnpm", "test": "jest --passWithNoTests" }, + "dependencies": { + "@swc/helpers": "0.5.1", + "assert": "2.0.0", + "browserify-zlib": "0.2.0", + "buffer": "6.0.3", + "console-browserify": "1.2.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "domain-browser": "4.19.0", + "events": "3.3.0", + "filter-obj": "2.0.2", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", + "path-browserify": "1.0.1", + "process": "0.11.10", + "punycode": "2.1.1", + "querystring-es3": "0.2.1", + "readable-stream": "3.6.0", + "stream-browserify": "3.0.0", + "stream-http": "3.2.0", + "string_decoder": "1.3.0", + "timers-browserify": "2.0.12", + "tty-browserify": "0.0.1", + "url": "0.11.0", + "util": "0.12.4", + "vm-browserify": "1.1.2" + }, "devDependencies": { - "@types/jest": "^29", - "@types/node": "^14", - "typescript": "^5", + "@modern-js/module-tools": "workspace:*", "@scripts/build": "workspace:*", - "jest": "^29", - "@scripts/jest-config": "workspace:*", - "@swc/helpers": "0.5.1", - "@modern-js/module-tools": "workspace:*" + "@types/node": "^14", + "typescript": "^5" }, "peerDependencies": { "@modern-js/module-tools": "workspace:^2.35.1" @@ -42,13 +65,10 @@ "optional": true } }, - "dependencies": { - "@modern-js/libuild-plugin-node-polyfill": "workspace:*" - }, "publishConfig": { - "registry": "https://registry.npmjs.org/", "access": "public", "provenance": true, + "registry": "https://registry.npmjs.org/", "types": "./dist/index.d.ts" } } diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/globals.js b/packages/module/plugin-module-node-polyfill/src/globals.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/globals.js rename to packages/module/plugin-module-node-polyfill/src/globals.js diff --git a/packages/module/plugin-module-node-polyfill/src/index.ts b/packages/module/plugin-module-node-polyfill/src/index.ts index a86f91d6c2aa..4271b7aa0c33 100644 --- a/packages/module/plugin-module-node-polyfill/src/index.ts +++ b/packages/module/plugin-module-node-polyfill/src/index.ts @@ -1,19 +1,113 @@ -import type { CliPlugin, ModuleTools } from '@modern-js/module-tools'; -import type { NodePolyfillPluginOptions } from '@modern-js/libuild-plugin-node-polyfill'; -import { nodePolyfillPlugin } from '@modern-js/libuild-plugin-node-polyfill'; +import path from 'path'; +import type { + CliPlugin, + ModuleTools, + EsbuildOptions, + ICompiler, +} from '@modern-js/module-tools'; +import { excludeObjectKeys, addResolveFallback } from './utils'; + +export interface NodePolyfillPluginOptions { + // like https://github.com/Richienb/node-polyfill-webpack-plugin#excludealiases + excludes?: string[]; + // override built-in node polyfill config, such as `fs`. + overrides?: Partial>; +} + +export const modules = { + assert: require.resolve('assert/'), + buffer: require.resolve('buffer/'), + child_process: null, + cluster: null, + console: require.resolve('console-browserify'), + constants: require.resolve('constants-browserify'), + crypto: require.resolve('crypto-browserify'), + dgram: null, + dns: null, + domain: require.resolve('domain-browser'), + events: require.resolve('events/'), + fs: null, + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + module: null, + net: null, + os: require.resolve('os-browserify/browser'), + path: require.resolve('path-browserify'), + punycode: require.resolve('punycode/'), + process: require.resolve('process/browser'), + querystring: require.resolve('querystring-es3'), + readline: null, + repl: null, + stream: require.resolve('stream-browserify'), + _stream_duplex: require.resolve('readable-stream/lib/_stream_duplex'), + _stream_passthrough: require.resolve( + 'readable-stream/lib/_stream_passthrough', + ), + _stream_readable: require.resolve('readable-stream/lib/_stream_readable'), + _stream_transform: require.resolve('readable-stream/lib/_stream_transform'), + _stream_writable: require.resolve('readable-stream/lib/_stream_writable'), + string_decoder: require.resolve('string_decoder/'), + sys: require.resolve('util/'), + timers: require.resolve('timers-browserify'), + tls: null, + tty: require.resolve('tty-browserify'), + url: require.resolve('url/'), + util: require.resolve('util/'), + vm: require.resolve('vm-browserify'), + zlib: require.resolve('browserify-zlib'), +}; + +export const getNodePolyfillHook = ( + polyfillOption: NodePolyfillPluginOptions = {}, +) => { + const polyfillModules = { + ...excludeObjectKeys( + addResolveFallback(modules, polyfillOption.overrides), + polyfillOption.excludes ?? [], + ), + }; + const polyfillModulesKeys = Object.keys(polyfillModules); + return { + name: 'node-polyfill', + apply(compiler: ICompiler) { + const plugins: NonNullable['plugins']> = [ + { + name: 'example', + setup(build) { + build.onResolve({ filter: /.*/ }, args => { + if (polyfillModulesKeys.includes(args.path)) { + return { + path: polyfillModules[args.path], + }; + } + return undefined; + }); + }, + }, + ]; + const lastBuildOptions = compiler.buildOptions; + compiler.buildOptions = { + ...lastBuildOptions, + inject: [ + ...(lastBuildOptions.inject ?? []), + path.join(__dirname, 'globals.js'), + ], + plugins: [plugins[0], ...(lastBuildOptions.plugins ?? [])], + }; + }, + }; +}; export const modulePluginNodePolyfill = ( polyfillOption: NodePolyfillPluginOptions = {}, ): CliPlugin => ({ - name: 'polyfill-plugin', + name: '@modern-js/plugin-module-node-polyfill', setup() { return { - modifyLibuild(config, next) { - config.plugins = [ - ...(config.plugins ?? []), - nodePolyfillPlugin(polyfillOption), - ]; - return next(config); + beforeBuildTask(config) { + const hook = getNodePolyfillHook(polyfillOption); + config.hooks.push(hook); + return config; }, }; }, diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/child_process.js b/packages/module/plugin-module-node-polyfill/src/mock/child_process.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/child_process.js rename to packages/module/plugin-module-node-polyfill/src/mock/child_process.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/cluster.js b/packages/module/plugin-module-node-polyfill/src/mock/cluster.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/cluster.js rename to packages/module/plugin-module-node-polyfill/src/mock/cluster.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/dgram.js b/packages/module/plugin-module-node-polyfill/src/mock/dgram.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/dgram.js rename to packages/module/plugin-module-node-polyfill/src/mock/dgram.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/dns.js b/packages/module/plugin-module-node-polyfill/src/mock/dns.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/dns.js rename to packages/module/plugin-module-node-polyfill/src/mock/dns.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/fs.js b/packages/module/plugin-module-node-polyfill/src/mock/fs.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/fs.js rename to packages/module/plugin-module-node-polyfill/src/mock/fs.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/module.js b/packages/module/plugin-module-node-polyfill/src/mock/module.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/module.js rename to packages/module/plugin-module-node-polyfill/src/mock/module.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/net.js b/packages/module/plugin-module-node-polyfill/src/mock/net.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/net.js rename to packages/module/plugin-module-node-polyfill/src/mock/net.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/readline.js b/packages/module/plugin-module-node-polyfill/src/mock/readline.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/readline.js rename to packages/module/plugin-module-node-polyfill/src/mock/readline.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/repl.js b/packages/module/plugin-module-node-polyfill/src/mock/repl.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/repl.js rename to packages/module/plugin-module-node-polyfill/src/mock/repl.js diff --git a/packages/libuild/libuild-plugin-node-polyfill/src/mock/tls.js b/packages/module/plugin-module-node-polyfill/src/mock/tls.js similarity index 100% rename from packages/libuild/libuild-plugin-node-polyfill/src/mock/tls.js rename to packages/module/plugin-module-node-polyfill/src/mock/tls.js diff --git a/packages/module/plugin-module-node-polyfill/src/utils.ts b/packages/module/plugin-module-node-polyfill/src/utils.ts new file mode 100644 index 000000000000..274e6f865cf4 --- /dev/null +++ b/packages/module/plugin-module-node-polyfill/src/utils.ts @@ -0,0 +1,44 @@ +import path from 'path'; + +function filterObject( + object: Record, + filter: (id: string) => boolean, +) { + const filtered: Record = {}; + Object.keys(object).forEach(key => { + if (filter(key)) { + filtered[key] = object[key]; + } + }); + return filtered; +} +export function excludeObjectKeys( + object: Record, + keys: string[], +) { + return filterObject(object, key => !keys.includes(key)); +} + +export function addResolveFallback( + object: Record, + overrides: Record = {}, +) { + const keys = Object.keys(object); + const newObject: Record = {}; + for (const key of keys) { + if (object[key] === null) { + newObject[key] = path.join(__dirname, `./mock/${key}.js`); + } else { + newObject[key] = object[key] as string; + } + } + + const overridesKeys = Object.keys(overrides); + for (const key of overridesKeys) { + if (overrides[key]) { + newObject[key] = overrides[key]; + } + } + + return newObject; +} diff --git a/packages/module/plugin-module-polyfill/package.json b/packages/module/plugin-module-polyfill/package.json index 0eeb72ef049c..d2011d2260a6 100644 --- a/packages/module/plugin-module-polyfill/package.json +++ b/packages/module/plugin-module-polyfill/package.json @@ -1,6 +1,13 @@ { "name": "@modern-js/plugin-module-polyfill", - "description": "The polyfill plugin of Modern.js Module.", + "version": "2.35.1", + "description": "The polyfill plugin of Modern.js Module", + "keywords": [ + "react", + "framework", + "modern", + "modern.js" + ], "homepage": "https://modernjs.dev/module-tools", "bugs": "https://github.com/web-infra-dev/modern.js/issues", "repository": { @@ -9,47 +16,40 @@ "directory": "packages/module/plugin-module-polyfill" }, "license": "MIT", - "keywords": [ - "react", - "framework", - "modern", - "modern.js" - ], - "version": "2.35.1", - "types": "./src/index.ts", + "sideEffects": false, "main": "./dist/index.js", + "types": "./src/index.ts", "scripts": { - "prepublishOnly": "only-allow-pnpm", - "dev": "mdn build --watch", "build": "mdn build", + "dev": "mdn build --watch", + "prepublishOnly": "only-allow-pnpm", "test": "jest --passWithNoTests" }, + "dependencies": { + "@babel/core": "^7.22.5", + "@babel/plugin-syntax-jsx": "7.22.5", + "@babel/plugin-syntax-typescript": "7.22.5", + "@modern-js/plugin-module-babel": "workspace:*", + "babel-plugin-polyfill-corejs3": "0.5.2" + }, "devDependencies": { - "@types/jest": "^29", - "@types/node": "^14", - "typescript": "^5", + "@modern-js/module-tools": "workspace:*", "@scripts/build": "workspace:*", - "jest": "^29", "@scripts/jest-config": "workspace:*", "@swc/helpers": "0.5.1", - "@modern-js/module-tools": "workspace:*" + "@types/jest": "^29", + "@types/node": "^14", + "jest": "^29", + "typescript": "^5" }, "peerDependencies": { "@modern-js/module-tools": "workspace:^2.35.1", "core-js-pure": "^3.25.0" }, - "dependencies": { - "@babel/core": "^7.22.15", - "@babel/plugin-syntax-typescript": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@modern-js/libuild-plugin-babel": "workspace:*", - "babel-plugin-polyfill-corejs3": "0.5.2" - }, - "sideEffects": false, "publishConfig": { - "registry": "https://registry.npmjs.org/", "access": "public", "provenance": true, + "registry": "https://registry.npmjs.org/", "types": "./dist/index.d.ts" } } diff --git a/packages/module/plugin-module-polyfill/src/index.ts b/packages/module/plugin-module-polyfill/src/index.ts index 4feec9c69275..394a79d01bf0 100644 --- a/packages/module/plugin-module-polyfill/src/index.ts +++ b/packages/module/plugin-module-polyfill/src/index.ts @@ -1,33 +1,41 @@ import type { CliPlugin, ModuleTools } from '@modern-js/module-tools'; -import { babelPlugin } from '@modern-js/libuild-plugin-babel'; +import { getBabelHook } from '@modern-js/plugin-module-babel'; -// deprecated named export -export const ModulePolyfillPlugin = (options?: { +export type Options = { targets?: Record | string; -}): CliPlugin => ({ +}; + +export const getPolyfillHook = (options?: Options) => { + const plugins = [ + [require('@babel/plugin-syntax-typescript'), { isTSX: true }], + [require('@babel/plugin-syntax-jsx')], + [ + require('babel-plugin-polyfill-corejs3'), + { + method: 'usage-pure', + targets: options?.targets, + }, + ], + ]; + return getBabelHook({ + plugins, + }); +}; + +export const modulePluginPolyfill = ( + options?: Options, +): CliPlugin => ({ name: '@modern-js/plugin-module-polyfill', setup: () => ({ - modifyLibuild(config) { - const plugins = [ - [require('@babel/plugin-syntax-typescript'), { isTSX: true }], - [require('@babel/plugin-syntax-jsx')], - [ - require('babel-plugin-polyfill-corejs3'), - { - method: 'usage-pure', - targets: options?.targets, - }, - ], - ]; - config.plugins?.push( - babelPlugin({ - plugins, - }), - ); + beforeBuildTask(config) { + config.hooks.push(getPolyfillHook(options)); return config; }, }), }); -// right named export -export { ModulePolyfillPlugin as modulePluginPolyfill }; +/** + * deprecated named export + * @deprecated + */ +export const ModulePolyfillPlugin = modulePluginPolyfill; diff --git a/packages/module/plugin-module-target/.eslintrc.js b/packages/module/plugin-module-target/.eslintrc.js deleted file mode 100644 index 414a253db518..000000000000 --- a/packages/module/plugin-module-target/.eslintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - root: true, - extends: ['@modern-js'], - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, -}; diff --git a/packages/module/plugin-module-target/.npmignore b/packages/module/plugin-module-target/.npmignore deleted file mode 100644 index 353fddf17262..000000000000 --- a/packages/module/plugin-module-target/.npmignore +++ /dev/null @@ -1,31 +0,0 @@ -.DS_Store - -.pnp -.pnp.js -.env.local -.env.*.local -*.log* - -node_modules/ -*.tsbuildinfo -.eslintcache - -coverage/ -output/ -output_resource/ -tests/ - -.vscode/**/* -!.vscode/settings.json -!.vscode/extensions.json -.idea/ - -src/ - -modern.config.* -jest.config.js -.eslintrc.js -.eslintrc -tsconfig.json -CHANGELOG.md - diff --git a/packages/module/plugin-module-target/CHANGELOG.md b/packages/module/plugin-module-target/CHANGELOG.md deleted file mode 100644 index 7c93852937e6..000000000000 --- a/packages/module/plugin-module-target/CHANGELOG.md +++ /dev/null @@ -1,357 +0,0 @@ -# @modern-js/plugin-module-target - -## 2.35.1 - -### Patch Changes - -- Updated dependencies [ce24aad] - - @modern-js/module-tools@2.35.1 - -## 2.35.0 - -### Patch Changes - -- Updated dependencies [15b834f] - - @modern-js/module-tools@2.35.0 - -## 2.34.0 - -### Patch Changes - -- Updated dependencies [76af015] - - @modern-js/module-tools@2.34.0 - -## 2.33.1 - -### Patch Changes - -- Updated dependencies [c38570e] -- Updated dependencies [7ad82bd] - - @modern-js/module-tools@2.33.1 - -## 2.33.0 - -### Patch Changes - -- @modern-js/module-tools@2.33.0 - -## 2.32.1 - -### Patch Changes - -- @modern-js/module-tools@2.32.1 - -## 2.32.0 - -### Patch Changes - -- Updated dependencies [8d22b87] - - @modern-js/module-tools@2.32.0 - -## 2.31.2 - -### Patch Changes - -- @modern-js/module-tools@2.31.2 - -## 2.31.1 - -### Patch Changes - -- @modern-js/module-tools@2.31.1 - -## 2.31.0 - -### Patch Changes - -- Updated dependencies [4c03d9a] -- Updated dependencies [1882366] - - @modern-js/module-tools@2.31.0 - -## 2.30.0 - -### Patch Changes - -- Updated dependencies [c03be09] - - @modern-js/module-tools@2.30.0 - -## 2.29.0 - -### Patch Changes - -- Updated dependencies [6993eb6] -- Updated dependencies [0f680ec] - - @modern-js/module-tools@2.29.0 - -## 2.28.0 - -### Patch Changes - -- d3e52e4: chore(CI): update build config to improve vitest CI perf - - chore(CI): 更新构建配置来提升 vitest CI 性能 - -- Updated dependencies [3092f1f] -- Updated dependencies [118c1c0] -- Updated dependencies [b7a8c43] -- Updated dependencies [d3e52e4] - - @modern-js/module-tools@2.28.0 - -## 2.27.0 - -### Patch Changes - -- @modern-js/module-tools@2.27.0 - -## 2.26.0 - -### Patch Changes - -- Updated dependencies [54c484c] -- Updated dependencies [cc2e3b7] - - @modern-js/module-tools@2.26.0 - -## 2.25.2 - -### Patch Changes - -- Updated dependencies [a2a5bcd] - - @modern-js/module-tools@2.25.2 - -## 2.25.1 - -### Patch Changes - -- Updated dependencies [273e3cd] - - @modern-js/module-tools@2.25.1 - -## 2.25.0 - -### Patch Changes - -- Updated dependencies [9aa2c25] -- Updated dependencies [d287b7f] - - @modern-js/module-tools@2.25.0 - -## 2.24.0 - -### Patch Changes - -- Updated dependencies [53ba418] -- Updated dependencies [3b82675] -- Updated dependencies [7073297] - - @modern-js/module-tools@2.24.0 - -## 2.23.1 - -### Patch Changes - -- @modern-js/module-tools@2.23.1 - -## 2.23.0 - -### Patch Changes - -- 7e6fb5f: chore: publishConfig add provenance config - - chore: publishConfig 增加 provenance 配置 - -- Updated dependencies [7e6fb5f] -- Updated dependencies [21b7f86] -- Updated dependencies [d1ef55f] - - @modern-js/module-tools@2.23.0 - -## 2.22.1 - -### Patch Changes - -- @modern-js/module-tools@2.22.1 - -## 2.22.0 - -### Patch Changes - -- ad49140: chore: adjust output and package.json fields - chore: 调整包的产物格式以及 packgae.json 里的字段 -- e2913dd: chore: update module plugin docs and readme - chore: 更新模块插件的文档和 readme -- Updated dependencies [d19dc11] -- Updated dependencies [c890980] -- Updated dependencies [4b7488c] - - @modern-js/module-tools@2.22.0 - -## 2.21.1 - -### Patch Changes - -- @modern-js/module-tools@2.21.1 - -## 2.21.0 - -### Patch Changes - -- 26dcf3a: chore: bump typescript to v5 in devDependencies - - chore: 升级 devDependencies 中的 typescript 版本到 v5 - -- Updated dependencies [df43559] -- Updated dependencies [26dcf3a] -- Updated dependencies [ad78387] - - @modern-js/module-tools@2.21.0 - -## 2.20.0 - -### Patch Changes - -- Updated dependencies [6b9d90a] -- Updated dependencies [6b9d90a] - - @modern-js/module-tools@2.20.0 - -## 2.19.1 - -### Patch Changes - -- @modern-js/module-tools@2.19.1 - -## 2.19.0 - -### Patch Changes - -- @modern-js/module-tools@2.19.0 - -## 2.18.1 - -### Patch Changes - -- Updated dependencies [cdc9db1] -- Updated dependencies [b161968] - - @modern-js/module-tools@2.18.1 - -## 2.18.0 - -### Patch Changes - -- Updated dependencies [f65d3e8] - - @modern-js/module-tools@2.18.0 - -## 2.17.1 - -### Patch Changes - -- @modern-js/module-tools@2.17.1 - -## 2.17.0 - -### Patch Changes - -- @modern-js/module-tools@2.17.0 - -## 2.16.0 - -### Patch Changes - -- 4e876ab: chore: package.json include the monorepo-relative directory - - chore: 在 package.json 中声明 monorepo 的子路径 - -- Updated dependencies [b06f571] -- Updated dependencies [acc0a00] -- Updated dependencies [fd4a8a6] -- Updated dependencies [4e876ab] -- Updated dependencies [355d36e] -- Updated dependencies [b06f571] - - @modern-js/module-tools@2.16.0 - -## 2.15.0 - -### Patch Changes - -- @modern-js/module-tools@2.15.0 - -## 2.14.0 - -### Patch Changes - -- Updated dependencies [f08f3ab] -- Updated dependencies [432ac8b] - - @modern-js/module-tools@2.14.0 - -## 2.13.4 - -### Patch Changes - -- @modern-js/module-tools@2.13.4 - -## 2.13.3 - -### Patch Changes - -- Updated dependencies [c20e67d] - - @modern-js/module-tools@2.13.3 - -## 2.13.2 - -### Patch Changes - -- @modern-js/module-tools@2.13.2 - -## 2.13.1 - -### Patch Changes - -- @modern-js/module-tools@2.13.1 - -## 2.13.0 - -### Patch Changes - -- Updated dependencies [034f36b] -- Updated dependencies [88faab3] -- Updated dependencies [034f36b] -- Updated dependencies [79bc089] - - @modern-js/module-tools@2.13.0 - -## 2.12.0 - -### Patch Changes - -- 979b15f: chore: remove to module folder - chore: 移动至 module 文件夹 -- Updated dependencies [af705fa] -- Updated dependencies [0baa168] -- Updated dependencies [1cdb379] -- Updated dependencies [3936535] -- Updated dependencies [8a3fbbd] -- Updated dependencies [8bc2d12] - - @modern-js/module-tools@2.12.0 - -## 2.11.0 - -### Patch Changes - -- Updated dependencies [aa0a312] -- Updated dependencies [6118636] -- Updated dependencies [f1b2629] - - @modern-js/module-tools@2.11.0 - -## 2.10.0 - -### Patch Changes - -- 0da32d0: chore: upgrade jest and puppeteer - chore: 升级 jest 和 puppeteer 到 latest -- Updated dependencies [0da32d0] - - @modern-js/module-tools@2.10.0 - -## 2.9.0 - -### Patch Changes - -- @modern-js/module-tools@2.9.0 - -## 2.8.0 - -### Patch Changes - -- Updated dependencies [adf68ec3ed] - - @modern-js/module-tools@2.8.0 diff --git a/packages/module/plugin-module-target/LICENSE b/packages/module/plugin-module-target/LICENSE deleted file mode 100644 index 39e3c5971226..000000000000 --- a/packages/module/plugin-module-target/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021-present Modern.js - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/module/plugin-module-target/README.md b/packages/module/plugin-module-target/README.md deleted file mode 100644 index db0ca2b74447..000000000000 --- a/packages/module/plugin-module-target/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Deprecated Package - -This package will be deprecated when next major version release and will no longer be maintained. - -In 2.x, you can still use it. - -We recommend that you use an alternative solution instead. - -## Alternatives - -- [esbuildOptions](https://modernjs.dev/module-tools/api/config/build-config.html#esbuildoptions) - -You can use esbuildOptions to set esbuild target directly after 2.14.0. diff --git a/packages/module/plugin-module-target/jest.config.js b/packages/module/plugin-module-target/jest.config.js deleted file mode 100644 index 5fcd3e5b28bd..000000000000 --- a/packages/module/plugin-module-target/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const sharedConfig = require('@scripts/jest-config'); - -/** @type {import('@jest/types').Config.InitialOptions} */ -module.exports = { - ...sharedConfig, - rootDir: __dirname, -}; diff --git a/packages/module/plugin-module-target/modern.config.js b/packages/module/plugin-module-target/modern.config.js deleted file mode 100644 index c2bf3e85b393..000000000000 --- a/packages/module/plugin-module-target/modern.config.js +++ /dev/null @@ -1,5 +0,0 @@ -const { tscLikeBuildConfig } = require('@scripts/build'); - -module.exports = { - buildConfig: tscLikeBuildConfig, -}; diff --git a/packages/module/plugin-module-target/package.json b/packages/module/plugin-module-target/package.json deleted file mode 100644 index e4f46f91e5a2..000000000000 --- a/packages/module/plugin-module-target/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@modern-js/plugin-module-target", - "description": "The target plugin of Modern.js Module.", - "homepage": "https://modernjs.dev/module-tools", - "bugs": "https://github.com/web-infra-dev/modern.js/issues", - "repository": { - "type": "git", - "url": "https://github.com/web-infra-dev/modern.js", - "directory": "packages/module/plugin-module-target" - }, - "license": "MIT", - "keywords": [ - "react", - "framework", - "modern", - "modern.js" - ], - "version": "2.35.1", - "types": "./src/index.ts", - "main": "./dist/index.js", - "scripts": { - "prepublishOnly": "only-allow-pnpm", - "dev": "modern-lib build --watch", - "build": "modern-lib build", - "test": "jest --passWithNoTests" - }, - "devDependencies": { - "@types/jest": "^29", - "@types/node": "^14", - "typescript": "^5", - "@scripts/build": "workspace:*", - "jest": "^29", - "@scripts/jest-config": "workspace:*", - "@swc/helpers": "0.5.1", - "@modern-js/module-tools": "workspace:*" - }, - "peerDependencies": { - "@modern-js/module-tools": "workspace:^2.35.1" - }, - "sideEffects": false, - "publishConfig": { - "registry": "https://registry.npmjs.org/", - "access": "public", - "provenance": true, - "types": "./dist/index.d.ts" - } -} diff --git a/packages/module/plugin-module-target/src/index.ts b/packages/module/plugin-module-target/src/index.ts deleted file mode 100644 index f4f530f0cea8..000000000000 --- a/packages/module/plugin-module-target/src/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { CliPlugin, ModuleTools } from '@modern-js/module-tools'; - -export const ModuleTargetPlugin = ( - // refer: https://esbuild.github.io/api/#target - options: { target: string[] }, -): CliPlugin => ({ - name: 'module-target', - setup: () => ({ - modifyLibuild(config) { - config.esbuildOptions = c => { - c.target = options.target; - return c; - }; - return config; - }, - }), -}); diff --git a/packages/module/plugin-module-target/tsconfig.json b/packages/module/plugin-module-target/tsconfig.json deleted file mode 100644 index e02117a9771c..000000000000 --- a/packages/module/plugin-module-target/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@modern-js/tsconfig/base", - "compilerOptions": { - "declaration": false, - "jsx": "preserve", - "baseUrl": "./", - "isolatedModules": true, - "paths": {} - }, - "include": ["src"] -} diff --git a/packages/solutions/module-tools/.eslintrc.js b/packages/solutions/module-tools/.eslintrc.js index 1a89e4c869d0..ef2c4a4af0ec 100644 --- a/packages/solutions/module-tools/.eslintrc.js +++ b/packages/solutions/module-tools/.eslintrc.js @@ -8,7 +8,9 @@ module.exports = { }, rules: { // https://eslint.org/docs/rules/complexity - complexity: ['warn', { max: 40 }], + complexity: ['warn', { max: 60 }], + 'consistent-return': [0], + 'node/prefer-global/buffer': [0], }, ignorePatterns: ['types.d.ts', 'compiled/'], }; diff --git a/packages/solutions/module-tools/jest.config.js b/packages/solutions/module-tools/jest.config.js deleted file mode 100644 index 7e4971f69472..000000000000 --- a/packages/solutions/module-tools/jest.config.js +++ /dev/null @@ -1,11 +0,0 @@ -const sharedConfig = require('@scripts/jest-config'); - -/** @type {import('@jest/types').Config.InitialOptions} */ -module.exports = { - ...sharedConfig, - rootDir: __dirname, - testEnvironment: '../../../tests/jest.env.js', - testMatch: ['/tests/**/*.test.[jt]s?(x)'], - testPathIgnorePatterns: ['buildWatch.test.ts'], - coveragePathIgnorePatterns: ['onExit.ts', './src/constants/*'], -}; diff --git a/packages/solutions/module-tools/modern.config.js b/packages/solutions/module-tools/modern.config.js index 66d10db8aab6..85ca2c6077ef 100644 --- a/packages/solutions/module-tools/modern.config.js +++ b/packages/solutions/module-tools/modern.config.js @@ -5,16 +5,8 @@ module.exports = { { buildType: 'bundleless', format: 'cjs', - // autoExternal: false, - // externals: [ - // /node_modules/, - // '@modern-js/plugin-lint', - // '@modern-js/plugin-changeset', - // ], target: 'es2019', - sourceMap: true, externalHelpers: true, - // disableSwcTransform: true, dts: dtsConfig, }, ], diff --git a/packages/solutions/module-tools/package.json b/packages/solutions/module-tools/package.json index 2f6adbf98eed..f4e241a533f9 100644 --- a/packages/solutions/module-tools/package.json +++ b/packages/solutions/module-tools/package.json @@ -1,6 +1,13 @@ { "name": "@modern-js/module-tools", + "version": "2.35.1", "description": "Simple, powerful, high-performance modern npm package development solution.", + "keywords": [ + "modern", + "modern.js", + "module-tools", + "lib-tools" + ], "homepage": "https://modernjs.dev/module-tools", "bugs": "https://github.com/web-infra-dev/modern.js/issues", "repository": { @@ -9,19 +16,6 @@ "directory": "packages/solutions/module-tools" }, "license": "MIT", - "keywords": [ - "modern", - "modern.js", - "module-tools", - "lib-tools" - ], - "version": "2.35.1", - "bin": { - "modern": "./bin/modern.js", - "modern-module": "./bin/modern.js" - }, - "types": "./src/index.ts", - "main": "./src/index.ts", "exports": { ".": { "jsnext:source": "./src/index.ts", @@ -32,6 +26,8 @@ "default": "./dist/config/defineConfig.js" } }, + "main": "./src/index.ts", + "types": "./src/index.ts", "typesVersions": { "*": { "types": [ @@ -45,60 +41,95 @@ ] } }, - "engines": { - "node": ">=14.0.0" + "bin": { + "modern": "./bin/modern.js", + "modern-module": "./bin/modern.js" }, "scripts": { - "prepublishOnly": "only-allow-pnpm", "build": "modern-lib build", "dev": "modern-lib build --watch", - "test": "jest", - "new": "modern-lib new" + "new": "modern-lib new", + "prepublishOnly": "only-allow-pnpm", + "test": "vitest run", + "test:ui": "vitest --ui", + "test:watch": "vitest dev --no-coverage" }, "dependencies": { - "@babel/parser": "^7.22.15", - "@babel/generator": "^7.22.15", - "@babel/types": "^7.22.15", - "@babel/traverse": "^7.22.15", + "@ast-grep/napi": "0.12.0", + "@babel/generator": "^7.21.5", + "@babel/parser": "^7.21.8", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", "@modern-js/core": "workspace:*", - "@modern-js/libuild": "workspace:*", - "@modern-js/libuild-plugin-svgr": "workspace:*", - "@modern-js/libuild-plugin-swc": "workspace:*", "@modern-js/new-action": "workspace:*", "@modern-js/plugin": "workspace:*", "@modern-js/plugin-changeset": "workspace:*", "@modern-js/plugin-i18n": "workspace:*", "@modern-js/plugin-lint": "workspace:*", + "@modern-js/swc-plugins": "0.5.5", "@modern-js/types": "workspace:*", "@modern-js/upgrade": "workspace:*", "@modern-js/utils": "workspace:*", + "@svgr/core": "8.0.0", + "@svgr/plugin-jsx": "8.0.1", + "@svgr/plugin-svgo": "8.0.1", + "@swc/helpers": "0.5.1", + "esbuild": "0.19.2", "postcss": "8.4.27", - "@swc/helpers": "0.5.1" + "source-map": "0.7.4", + "source-map-support": "0.5.20", + "style-inject": "0.3.0", + "sucrase": "3.29.0", + "terser": "5.15.0" }, "devDependencies": { + "@ampproject/remapping": "1.0.2", + "@babel/code-frame": "7.16.7", "@modern-js/builder-webpack-provider": "workspace:*", "@modern-js/self": "workspace:@modern-js/module-tools@*", + "@rollup/pluginutils": "4.1.1", "@scripts/build": "workspace:*", - "@scripts/jest-config": "workspace:*", + "@scripts/vitest-config": "workspace:*", "@types/babel__generator": "7.6.4", "@types/babel__traverse": "7.18.5", - "@types/fs-extra": "9.0.13", - "@types/jest": "^29", + "@types/convert-source-map": "1.5.2", + "@types/mime-types": "2.1.1", + "@types/mocha": "9.0.0", "@types/node": "^14", - "detect-indent": "6.1.0", - "fs-extra": "10.1.0", - "jest": "^29", - "path-browserify": "1.0.1", - "postcss-alias": "2.0.0", - "react": "^18", + "@types/picomatch": "2.3.0", + "@types/source-map-support": "0.5.4", + "@types/stack-trace": "0.0.30", + "chokidar": "3.5.2", + "convert-source-map": "1.8.0", + "enhanced-resolve": "5.8.3", + "magic-string": "0.26.4", + "mime-types": "2.1.33", + "picomatch": "2.3.0", + "postcss-modules": "4.3.0", + "rimraf": "3.0.2", + "safe-identifier": "0.4.2", + "tapable": "2.2.1", + "tsconfig-paths": "4.1.1", + "tsconfig-paths-webpack-plugin": "4.0.0", "typescript": "^5" }, + "peerDependencies": { + "typescript": "^4 || ^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, + "engines": { + "node": ">=14.0.0" + }, "publishConfig": { - "registry": "https://registry.npmjs.org/", "access": "public", + "main": "./dist/index.js", "provenance": true, + "registry": "https://registry.npmjs.org/", "types": "./dist/index.d.ts", - "main": "./dist/index.js", "typesVersions": { "*": { "types": [ @@ -112,13 +143,5 @@ ] } } - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - }, - "peerDependencies": { - "typescript": "^4 || ^5" } } diff --git a/packages/solutions/module-tools/src/build.ts b/packages/solutions/module-tools/src/build.ts index 66f638331127..05419b09874a 100644 --- a/packages/solutions/module-tools/src/build.ts +++ b/packages/solutions/module-tools/src/build.ts @@ -1,9 +1,7 @@ import type { PluginAPI } from '@modern-js/core'; -import { createDebugger } from '@modern-js/utils'; +import { debug } from './debug'; import type { ModuleTools, ModuleContext, BuildCommandOptions } from './types'; -const debug = createDebugger('module-tools'); - export const build = async ( api: PluginAPI, options: BuildCommandOptions, @@ -17,15 +15,24 @@ export const build = async ( const runner = api.useHookRunners(); + debug('normalize build config'); + const { normalizeBuildConfig } = await import('./config/normalize'); const resolvedBuildConfig = await normalizeBuildConfig(api, context, options); - debug('resolvedBuildConfig', resolvedBuildConfig); + debug('normalize build config done'); + + debug('normalizedBuildConfig', resolvedBuildConfig); + + debug('run beforeBuild hooks'); await runner.beforeBuild({ config: resolvedBuildConfig, cliOptions: options, }); + + debug('run beforeBuild hooks done'); + const builder = await import('./builder'); await builder.run({ cmdOptions: options, resolvedBuildConfig, context }, api); }; diff --git a/packages/solutions/module-tools/src/builder/build.ts b/packages/solutions/module-tools/src/builder/build.ts index 737d8d2897c4..9067615935a1 100644 --- a/packages/solutions/module-tools/src/builder/build.ts +++ b/packages/solutions/module-tools/src/builder/build.ts @@ -1,6 +1,4 @@ -import { resolve } from 'path'; -import type { CLIConfig } from '@modern-js/libuild'; -import { slash, logger } from '@modern-js/utils'; +import { slash, logger, fs } from '@modern-js/utils'; import type { BuildCommandOptions, BaseBuildConfig, @@ -8,10 +6,11 @@ import type { PluginAPI, DTSOptions, ModuleContext, - TsTarget, } from '../types'; import pMap from '../../compiled/p-map'; +import { debug, label } from '../debug'; import { copyTask } from './copy'; +import { createCompiler } from './esbuild'; export const runBuildTask = async ( options: { @@ -22,60 +21,28 @@ export const runBuildTask = async ( api: PluginAPI, ) => { const { buildConfig, context, buildCmdOptions } = options; - const { appDirectory, isTsProject } = context; + const { appDirectory } = context; await copyTask(buildConfig, { appDirectory, watch: buildCmdOptions.watch }); - if (isTsProject) { - await buildInTsProject(options, api); - } else { - await buildInJsProject(options, api); - } -}; - -export const buildInTsProject = async ( - options: { - buildConfig: BaseBuildConfig; - buildCmdOptions: BuildCommandOptions; - context: ModuleContext; - }, - api: PluginAPI, -) => { - const { buildConfig, buildCmdOptions } = options; const dts = buildCmdOptions.dts ? buildConfig.dts : false; - const skipBuildLib = buildConfig.dts ? buildConfig.dts.only : false; - const watch = buildCmdOptions.watch ?? false; + const { watch } = buildCmdOptions; + const existTsconfig = await fs.pathExists(buildConfig.tsconfig); - if (dts === false) { - // --no-dts and buildConfig is `{ dts: { only: true } }`, then skip. - !skipBuildLib && (await buildLib(buildConfig, api, { watch })); - } else { + if (dts && existTsconfig) { const tasks = dts.only ? [generatorDts] : [buildLib, generatorDts]; await pMap(tasks, async task => { - await task(buildConfig, api as any, { watch, dts }); + await task(buildConfig, api, { watch, dts }); }); + } else { + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain + if (dts && dts.only) { + return; + } + await buildLib(buildConfig, api, { watch }); } }; -export const buildInJsProject = async ( - options: { - buildConfig: BaseBuildConfig; - buildCmdOptions: BuildCommandOptions; - context: ModuleContext; - }, - api: PluginAPI, -) => { - const { buildConfig, buildCmdOptions } = options; - const dts = buildCmdOptions.dts ? buildConfig.dts : false; - const watch = buildCmdOptions.watch ?? false; - - if (dts !== false && dts.only) { - return; - } - - await buildLib(buildConfig, api, { watch }); -}; - export const generatorDts = async ( config: BaseBuildConfig, api: PluginAPI, @@ -86,31 +53,44 @@ export const generatorDts = async ( ) => { const { runRollup, runTsc } = await import('./dts'); const { watch, dts } = options; - const { buildType, input, sourceDir, alias, externals } = config; + const { + buildType, + input, + sourceDir, + alias, + externals, + tsconfig, + footer: { dts: footer }, + banner: { dts: banner }, + } = config; const { appDirectory } = api.useAppContext(); - const { tsconfigPath, distPath, abortOnError, respectExternal } = dts; + const { distPath, abortOnError, respectExternal } = dts; + + // remove this line after remove dts.tsconfigPath + const tsconfigPath = dts.tsconfigPath ?? tsconfig; + + const generatorDtsConfig = { + distPath, + watch, + externals, + input, + tsconfigPath, + abortOnError, + respectExternal, + appDirectory, + footer, + banner, + alias, + sourceDir, + }; + const prevTime = Date.now(); + debug(`${label('dts')} Build Start`); if (buildType === 'bundle') { - await runRollup(api, { - distDir: distPath, - watch, - externals, - input, - tsconfigPath, - abortOnError, - respectExternal, - appDirectory, - }); + await runRollup(api, generatorDtsConfig); } else { - await runTsc(api, { - appDirectory, - alias, - distAbsPath: distPath, - watch, - tsconfigPath, - sourceDir, - abortOnError, - }); + await runTsc(api, generatorDtsConfig); } + debug(`${label('dts')} Build success in ${Date.now() - prevTime}ms`); }; export const buildLib = async ( @@ -121,195 +101,29 @@ export const buildLib = async ( }, ) => { const { watch } = options; - const { - target, - buildType, - sourceMap, - format, - outDir: distPath, - asset, - jsx, - input, - platform, - splitting, - minify, - sourceDir, - umdGlobals, - umdModuleName, - define, - alias, - style, - externals, - autoExternal, - dts, - metafile, - sideEffects, - redirect, - esbuildOptions, - externalHelpers, - transformImport, - transformLodash, - sourceType, - disableSwcTransform, - } = config; + const { target, buildType, format, externalHelpers } = config; const { appDirectory } = api.useAppContext(); const root = slash(appDirectory); - const outdir = slash(distPath); - const assetOutDir = asset.path ? slash(asset.path) : asset.path; - const { less, sass, postcss, inject, modules, autoModules } = style; - - // support swc-transform, umd and emitDecoratorMetadata by swc - const { - umdPlugin, - swcTransformPlugin, - transformPlugin: legacyTransformPlugin, - es5Plugin, - } = await import('@modern-js/libuild-plugin-swc'); - const { - checkSwcHelpers, - matchEs5PluginCondition, - matchSwcTransformCondition, - } = await import('../utils/builder'); - - const { getProjectTsconfig } = await import('../utils/dts'); - const tsconfigPath = dts - ? dts.tsconfigPath - : resolve(appDirectory, 'tsconfig.json'); - const userTsconfig = await getProjectTsconfig(tsconfigPath); - - const plugins = []; - - if ( - matchSwcTransformCondition({ - sourceType, - buildType, - format, - disableSwcTransform, - }) - ) { - // TODO: refactor config plugins logic - - const { tsTargetAtOrAboveES2022 } = await import('../utils/dts'); - const tsUseDefineForClassFields = - userTsconfig?.compilerOptions?.useDefineForClassFields; - let tsTarget = userTsconfig?.compilerOptions?.target; - tsTarget = tsTarget ? (tsTarget.toLowerCase() as TsTarget) : undefined; - let useDefineForClassFields: boolean; - if (tsUseDefineForClassFields !== undefined) { - useDefineForClassFields = tsUseDefineForClassFields; - } else if (tsTarget !== undefined) { - useDefineForClassFields = tsTargetAtOrAboveES2022(tsTarget); - } else { - useDefineForClassFields = true; - } - - plugins.push( - swcTransformPlugin({ - pluginImport: transformImport, - transformLodash, - externalHelpers: Boolean(externalHelpers), - emitDecoratorMetadata: - userTsconfig?.compilerOptions?.emitDecoratorMetadata, - useDefineForClassFields, - }), - ); - } else { - if ( - matchEs5PluginCondition({ - sourceType, - buildType, - format, - target, - disableSwcTransform, - }) - ) { - plugins.push(es5Plugin()); - } - - if (userTsconfig?.compilerOptions?.emitDecoratorMetadata) { - plugins.push( - legacyTransformPlugin({ - jsc: { - transform: { - legacyDecorator: true, - decoratorMetadata: true, - }, - }, - }), - ); - } - } - - if (format === 'umd') { - plugins.push(umdPlugin(umdModuleName)); - } + const { checkSwcHelpers } = await import('../utils/builder'); await checkSwcHelpers({ appDirectory, externalHelpers }); - // support svgr - if (asset.svgr) { - const { svgrPlugin } = await import('@modern-js/libuild-plugin-svgr'); - const options = typeof asset.svgr === 'boolean' ? {} : asset.svgr; - plugins.push(svgrPlugin(options)); - } - - // adapt module tools - const { watchPlugin } = await import('../utils/libuild-plugin'); - plugins.push(watchPlugin(api, config)); - - const buildConfig: CLIConfig = { - root, - watch, - target, - sourceMap, - format, - outdir, - define, - style: { - less, - sass, - postcss, - inject, - modules, - autoModules, - }, - resolve: { - alias, - }, - asset: { - ...asset, - outdir: assetOutDir, - }, - plugins, - jsx, - input, - platform, - splitting, - minify, - sourceDir, - metafile: metafile && buildType === 'bundle', - globals: umdGlobals, - external: externals, - autoExternal, - redirect, - bundle: buildType === 'bundle', - sideEffects, - // outbase for [dir]/[name] - outbase: sourceDir, - esbuildOptions, - }; - try { - const { Libuilder } = await import('@modern-js/libuild'); - const { addOutputChunk } = await import('../utils/print'); - const runner = api.useHookRunners(); - const modifiedBuildConfig = await runner.modifyLibuild(buildConfig, { - onLast: c => c, + const prevTime = Date.now(); + debug(`${label(config.format)} Build Start`); + const compiler = await createCompiler({ + config, + watch, + root: appDirectory, + api, }); + await compiler.build(); + debug( + `${label(config.format)} Build success in ${Date.now() - prevTime}ms`, + ); - const builder = await Libuilder.create(modifiedBuildConfig); - await builder.build(); - addOutputChunk(builder.outputChunk, root, buildType === 'bundle'); + const { addOutputChunk } = await import('../utils/print'); + addOutputChunk(compiler.outputChunk, root, buildType === 'bundle'); if (watch) { const { watchSectionTitle } = await import('../utils/log'); diff --git a/packages/solutions/module-tools/src/builder/clear.ts b/packages/solutions/module-tools/src/builder/clear.ts index d67053ab95cf..635929dab0e1 100644 --- a/packages/solutions/module-tools/src/builder/clear.ts +++ b/packages/solutions/module-tools/src/builder/clear.ts @@ -9,17 +9,8 @@ export const clearDtsTemp = async () => { export const clearBuildConfigPaths = async ( configs: BaseBuildConfig[], - options?: { - noClear?: boolean; - projectAbsRootPath?: string; - }, + projectAbsRootPath: string, ) => { - const { noClear = false, projectAbsRootPath = process.cwd() } = options ?? {}; - - if (noClear) { - return; - } - for (const config of configs) { if (projectAbsRootPath === config.outDir) { logger.warn(chalk.bgYellowBright(i18n.t(localeKeys.warns.clearRootPath))); diff --git a/packages/solutions/module-tools/src/builder/copy.ts b/packages/solutions/module-tools/src/builder/copy.ts index 1460f28f0acb..acb0adb3386b 100644 --- a/packages/solutions/module-tools/src/builder/copy.ts +++ b/packages/solutions/module-tools/src/builder/copy.ts @@ -1,15 +1,9 @@ import path from 'path'; -import { - watch, - fs, - logger, - createDebugger, - globby, - fastGlob, -} from '@modern-js/utils'; +import { watch, fs, logger, globby, fastGlob } from '@modern-js/utils'; import type { CopyOptions, CopyPattern } from '../types/config/copy'; import type { BaseBuildConfig } from '../types/config'; import pMap from '../../compiled/p-map'; +import { debug } from '../debug'; const watchMap = new Map(); @@ -155,8 +149,6 @@ export const watchCopyFiles = async ( }, copyConfig: CopyOptions, ) => { - const debug = createDebugger('module-tools:copy-watch'); - debug('watchMap', watchMap); const { SectionTitleStatus, CopyLogPrefix } = await import( @@ -215,7 +207,7 @@ export const copyTask = async ( if (!copyConfig.patterns || copyConfig.patterns.length === 0) { return; } - + debug('run copy task'); const concurrency = copyConfig?.options?.concurrency || 100; try { await pMap( @@ -235,6 +227,8 @@ export const copyTask = async ( logger.error(`copy error: ${e.message}`); } } + debug('run copy task done'); + if (options.watch) { await watchCopyFiles(options, copyConfig); } diff --git a/packages/solutions/module-tools/src/builder/dts/rollup.ts b/packages/solutions/module-tools/src/builder/dts/rollup.ts index 408283c7a952..70b187eb7a19 100644 --- a/packages/solutions/module-tools/src/builder/dts/rollup.ts +++ b/packages/solutions/module-tools/src/builder/dts/rollup.ts @@ -1,5 +1,5 @@ import path from 'path'; -import { logger } from '@modern-js/utils/logger'; +import { logger } from '@modern-js/utils'; import ts from 'typescript'; import type { InputOptions, @@ -8,32 +8,21 @@ import type { RollupWatcher, } from '../../../compiled/rollup'; import type { - BaseBuildConfig, + GeneratorDtsConfig, Input, PluginAPI, ModuleTools, } from '../../types'; import jsonPlugin from '../../../compiled/@rollup/plugin-json'; import dtsPlugin from '../../../compiled/rollup-plugin-dts'; -import { mapValue, transformUndefineObject } from '../../utils/common'; +import { mapValue, transformUndefineObject } from '../../utils'; export type { RollupWatcher }; -type Config = { - distDir: string; - tsconfigPath: string; - externals: BaseBuildConfig['externals']; - input: Input; - watch: boolean; - abortOnError: boolean; - respectExternal: boolean; - appDirectory: string; -}; - export const runRollup = async ( api: PluginAPI, { - distDir, + distPath, tsconfigPath, externals, input, @@ -41,7 +30,9 @@ export const runRollup = async ( abortOnError, respectExternal, appDirectory, - }: Config, + footer, + banner, + }: GeneratorDtsConfig, ) => { const ignoreFiles: Plugin = { name: 'ignore-files', @@ -114,13 +105,15 @@ export const runRollup = async ( ].filter(Boolean), }; const outputConfig: OutputOptions = { - dir: distDir, + dir: distPath, format: 'esm', exports: 'named', + footer, + banner, }; if (watch) { const { watch } = await import('../../../compiled/rollup'); - const { watchSectionTitle } = await import('../../utils/log'); + const { watchSectionTitle } = await import('../../utils'); const { SectionTitleStatus, BundleDtsLogPrefix } = await import( '../../constants/log' ); @@ -150,13 +143,13 @@ export const runRollup = async ( } else { try { const { rollup } = await import('../../../compiled/rollup'); - const { addRollupChunk } = await import('../../utils/print'); + const { addRollupChunk } = await import('../../utils'); const bundle = await rollup(inputConfig); const rollupOutput = await bundle.write(outputConfig); addRollupChunk(rollupOutput, appDirectory, outputConfig.dir!); return bundle; } catch (e) { - const { printOrThrowDtsErrors } = await import('../../utils/dts'); + const { printOrThrowDtsErrors } = await import('../../utils'); await printOrThrowDtsErrors(e, { abortOnError, buildType: 'bundle' }); return null; } diff --git a/packages/solutions/module-tools/src/builder/dts/tsc.ts b/packages/solutions/module-tools/src/builder/dts/tsc.ts index bfea8d4effa2..b9c531bc85f5 100644 --- a/packages/solutions/module-tools/src/builder/dts/tsc.ts +++ b/packages/solutions/module-tools/src/builder/dts/tsc.ts @@ -1,18 +1,21 @@ import type { ChildProcess } from 'child_process'; import { execa, logger } from '@modern-js/utils'; -import { addDtsFiles } from '../../utils/print'; import type { - BundlelessGeneratorDtsConfig, + GeneratorDtsConfig, PluginAPI, ModuleTools, + GeneratedDtsInfo, } from '../../types'; import { - generatorTsConfig, + generateDtsInfo, getTscBinPath, printOrThrowDtsErrors, resolveAlias, -} from '../../utils/dts'; -import { watchSectionTitle } from '../../utils/log'; + watchSectionTitle, + addDtsFiles, + writeDtsFiles, + addBannerAndFooter, +} from '../../utils'; import { BundlelessDtsLogPrefix, SectionTitleStatus, @@ -53,15 +56,14 @@ const resolveLog = async ( }); }; -const generatorDts = async ( +const runTscBin = async ( api: PluginAPI, - config: BundlelessGeneratorDtsConfig, + config: GeneratorDtsConfig, + info: GeneratedDtsInfo, ) => { const { appDirectory, watch = false, abortOnError = true } = config; - const { userTsconfig, generatedTsconfig: result } = await generatorTsConfig( - config, - ); + const { tempTsconfigPath } = info; const tscBinFile = await getTscBinPath(appDirectory); @@ -70,7 +72,7 @@ const generatorDts = async ( tscBinFile, [ '-p', - result.tempTsconfigPath, + tempTsconfigPath, /* Required parameter, use it stdout have color */ '--pretty', // https://github.com/microsoft/TypeScript/issues/21824 @@ -87,7 +89,9 @@ const generatorDts = async ( resolveLog(childProgress, { watch, watchFn: async () => { - await resolveAlias(config, { ...result, userTsconfig }); + const result = await resolveAlias(config, info); + const dtsFiles = addBannerAndFooter(result, config.banner, config.footer); + await writeDtsFiles(config, info, dtsFiles); runner.buildWatchDts({ buildType: 'bundleless' }); }, }); @@ -97,15 +101,16 @@ const generatorDts = async ( } catch (e) { await printOrThrowDtsErrors(e, { abortOnError, buildType: 'bundleless' }); } - - return { ...result, userTsconfig }; }; export const runTsc = async ( api: PluginAPI, - config: BundlelessGeneratorDtsConfig, + config: GeneratorDtsConfig, ) => { - const result = await generatorDts(api, config); - await resolveAlias(config, result); - await addDtsFiles(config.distAbsPath, config.appDirectory); + const generatedDtsInfo = await generateDtsInfo(config); + await runTscBin(api, config, generatedDtsInfo); + const result = await resolveAlias(config, generatedDtsInfo); + const dtsFiles = addBannerAndFooter(result, config.banner, config.footer); + await writeDtsFiles(config, generatedDtsInfo, dtsFiles); + await addDtsFiles(config.distPath, config.appDirectory); }; diff --git a/packages/solutions/module-tools/src/builder/esbuild/adapter.ts b/packages/solutions/module-tools/src/builder/esbuild/adapter.ts new file mode 100644 index 000000000000..4286121ef68a --- /dev/null +++ b/packages/solutions/module-tools/src/builder/esbuild/adapter.ts @@ -0,0 +1,329 @@ +import { dirname, resolve, extname } from 'path'; +import module from 'module'; +import pm from 'picomatch'; +import { ImportKind, Loader, Plugin } from 'esbuild'; +import { fs, isString } from '@modern-js/utils'; +import { createFilter } from '@rollup/pluginutils'; +import { normalizeSourceMap, resolvePathAndQuery } from '../../utils'; +import { loaderMap } from '../../constants/loader'; +import { debugResolve } from '../../debug'; +import type { SideEffects, ICompiler } from '../../types'; +import { writeFile } from './write-file'; +import { initWatcher } from './watch'; + +/** + * esbuld's external will keep import statement as import|require statement, which + * is ok for node environment but will cause problem for browser environment(lack of commonjs runtime supports) + * so we need to support features like rollup's globals, which will convert an module id to global variable + * @example + * { + * externals: { + * 'jquery': '$' + * } + * } + * which will convert this code + * import jq from 'jquery' + * to + * const jq = globalThis['$'] + */ +const globalNamespace = 'globals'; + +const HTTP_PATTERNS = /^(https?:)?\/\//; +const DATAURL_PATTERNS = /^data:/; +const HASH_PATTERNS = /#[^#]+$/; +const DATAURL_JAVASCRIPT_PATTERNS = /^data:text\/javascript/; + +export const adapterPlugin = (compiler: ICompiler): Plugin => { + const { context } = compiler; + const { config, root } = context; + + return { + name: 'esbuild:adapter', + setup(build) { + build.onStart(() => { + context.watch && initWatcher(compiler); + }); + + build.onResolve({ filter: /.*/ }, async args => { + if (args.kind === 'url-token') { + return { + path: args.path, + external: true, + }; + } + + for (const [key] of Object.entries(config.umdGlobals)) { + const isMatch = pm(key); + if (isMatch(args.path)) { + debugResolve('resolve umdGlobals:', key); + return { + path: args.path, + namespace: globalNamespace, + }; + } + } + + /** + * The node: protocol was added to require in Node v14.18.0 + * https://nodejs.org/api/esm.html#node-imports + */ + if (/^node:/.test(args.path)) { + return { + path: args.path.slice(5), + external: true, + }; + } + + // esbuild cant handle return non absolute path from plugin, so we need to do a trick to handle this + // see https://github.com/evanw/esbuild/issues/2404 + if (DATAURL_JAVASCRIPT_PATTERNS.test(args.path)) { + return { + path: args.path, + namespace: 'dataurl', + }; + } + + // external url + const isUrl = (source: string) => + HTTP_PATTERNS.test(source) || + DATAURL_PATTERNS.test(source) || + HASH_PATTERNS.test(source); + if (isUrl(args.path)) { + return { + path: args.path, + external: true, + }; + } + + const { externals, sideEffects: userSideEffects } = config; + const regExternal = externals.filter( + (item): item is RegExp => !isString(item), + ); + const externalList = externals + .filter(isString) + .concat(config.platform === 'node' ? module.builtinModules : []); + const externalMap = externalList.reduce((map, item) => { + map.set(item, true); + return map; + }, new Map()); + + const getIsExternal = (name: string) => { + if (externalMap.get(name)) { + return true; + } + + if (regExternal.some(reg => reg.test(name))) { + return true; + } + + return false; + }; + + /** + * return module sideEffects + * @param filePath + * @param isExternal + * @returns + */ + const getSideEffects = async ( + filePath: string, + isExternal: boolean, + ) => { + let pkgPath = ''; + let sideEffects: SideEffects | undefined | string[] = userSideEffects; + let moduleSideEffects = true; + + if (typeof userSideEffects === 'undefined') { + let curDir = dirname(filePath); + try { + while (curDir !== dirname(curDir)) { + if (fs.existsSync(resolve(curDir, 'package.json'))) { + pkgPath = resolve(curDir, 'package.json'); + break; + } + curDir = dirname(curDir); + } + // eslint-disable-next-line prefer-destructuring + sideEffects = JSON.parse( + fs.readFileSync(pkgPath, 'utf-8'), + ).sideEffects; + } catch (err) { + // just ignore in case some system permission exception happens + } + if (!pkgPath) { + return undefined; + } + } + if (typeof sideEffects === 'boolean') { + moduleSideEffects = sideEffects; + } else if (Array.isArray(sideEffects)) { + moduleSideEffects = createFilter( + sideEffects.map(glob => { + if (typeof glob === 'string') { + if (!glob.includes('/')) { + return `**/${glob}`; + } + } + return glob; + }), + null, + pkgPath + ? { + resolve: dirname(pkgPath), + } + : undefined, + )(filePath); + } else if (typeof sideEffects === 'function') { + moduleSideEffects = sideEffects(filePath, isExternal); + } + return moduleSideEffects; + }; + + const getResultPath = (id: string, dir: string, kind: ImportKind) => { + return id.endsWith('.css') + ? compiler.css_resolve(id, dir) + : compiler.node_resolve(id, dir, kind); + }; + + const { originalFilePath, rawQuery } = resolvePathAndQuery(args.path); + const suffix = (rawQuery ?? '').length > 0 ? `?${rawQuery}` : ''; + const isExternal = getIsExternal(originalFilePath); + const dir = + args.resolveDir ?? (args.importer ? dirname(args.importer) : root); + const sideEffects = await getSideEffects(originalFilePath, isExternal); + const result = { + path: isExternal + ? args.path + : getResultPath(originalFilePath, dir, args.kind), + external: isExternal, + namespace: isExternal ? undefined : 'file', + sideEffects, + suffix, + }; + debugResolve('onResolve args:', args); + debugResolve('onResolve result:', result); + return result; + }); + build.onLoad({ filter: /.*/ }, async args => { + if (args.namespace === globalNamespace) { + const value = config.umdGlobals[args.path]; + return { + contents: `module.exports = (typeof globalThis !== "undefined" ? globalThis : Function('return this')() || global || self)[${JSON.stringify( + value, + )}]`, + }; + } + + if (args.suffix) { + args.path += args.suffix; + } + + if (args.namespace !== 'file') { + return; + } + + compiler.addWatchFile(args.path); + let result = await compiler.hooks.load.promise(args); + if (!result) { + // let esbuild to handle data:text/javascript + if (DATAURL_JAVASCRIPT_PATTERNS.test(args.path)) { + return; + } + result = { + contents: await fs.promises.readFile(args.path), + }; + } + + // file don't need transform when loader is copy + if (!result.contents || result.loader === 'copy') { + return result; + } + + const context = compiler.getTransformContext(args.path); + + context.addSourceMap(context.genPluginId('adapter'), result.map); + + const transformResult = await compiler.hooks.transform.promise({ + code: result.contents.toString(), + path: args.path, + loader: result.loader, + }); + + const ext = extname(args.path); + + const loader = (transformResult.loader ?? loaderMap[ext]) as Loader; + + const inlineSourceMap = context.getInlineSourceMap(); + + return { + contents: transformResult.code + inlineSourceMap, + loader, + resolveDir: result.resolveDir ?? dirname(args.path), + }; + }); + + build.onEnd(async result => { + if (result.errors.length) { + return; + } + const { outputs } = result.metafile!; + const needSourceMap = Boolean(config.sourceMap); + for (const [key, value] of Object.entries(outputs)) { + if (key.endsWith('.map')) { + continue; + } + const absPath = resolve(root, key); + const item = result.outputFiles?.find(x => x.path === absPath); + const mapping = result.outputFiles?.find( + x => + x.path.endsWith('.map') && + x.path.replace(/\.map$/, '') === absPath, + ); + if (!item) { + continue; + } + if (absPath.endsWith('.js')) { + compiler.emitAsset(absPath, { + type: 'chunk', + contents: item.text, + map: normalizeSourceMap(mapping?.text, { needSourceMap }), + fileName: absPath, + entryPoint: value?.entryPoint, + }); + } else { + compiler.emitAsset(absPath, { + type: 'asset', + contents: Buffer.from(item.contents), + fileName: absPath, + entryPoint: value?.entryPoint, + }); + } + } + + for (const [key, value] of compiler.outputChunk.entries()) { + const context = compiler.getSourcemapContext(value.fileName); + if (value.type === 'chunk' && config.sourceMap) { + context.addSourceMap(context.genPluginId('adapter'), value.map); + } + const processedResult = await compiler.hooks.renderChunk.promise( + value, + ); + if (processedResult.type === 'chunk' && config.sourceMap) { + processedResult.map = context.getSourceMap(); + } + compiler.outputChunk.set(key, processedResult); + } + + if (config.metafile) { + const now = Date.now(); + compiler.emitAsset( + resolve(config.outDir, `metafile-${now}.json`), + JSON.stringify(result.metafile!, null, 2), + ); + } + + await writeFile(compiler); + }); + }, + }; +}; diff --git a/packages/libuild/libuild-core/src/core/utils.ts b/packages/solutions/module-tools/src/builder/esbuild/hook.ts similarity index 84% rename from packages/libuild/libuild-core/src/core/utils.ts rename to packages/solutions/module-tools/src/builder/esbuild/hook.ts index fe2d70c7071b..0d0a02b90efd 100644 --- a/packages/libuild/libuild-core/src/core/utils.ts +++ b/packages/solutions/module-tools/src/builder/esbuild/hook.ts @@ -1,8 +1,8 @@ import { promisify } from 'util'; import * as tapable from 'tapable'; -import { Source, ILibuilder, Chunk } from '../types'; +import { Source, Chunk, ICompiler } from '../../types'; -export function createTransformHook(compiler: ILibuilder) { +export function createTransformHook(compiler: ICompiler) { const hook = new tapable.AsyncSeriesWaterfallHook(['args']); if (!compiler.config.transformCache) { @@ -35,17 +35,13 @@ export function createTransformHook(compiler: ILibuilder) { hook.tap = cacheFn; hook.tapPromise = cacheFn; - hook.tapAsync = function (options, fn) { - cacheFn(options, promisify(fn)); - }; - return hook; } -export function createProcessAssetHook(compiler: ILibuilder) { +export function createRenderChunkHook(compiler: ICompiler) { const hook = new tapable.AsyncSeriesWaterfallHook(['chunk']); - if (!compiler.config.sourceMap) { + if (!compiler.context.config.sourceMap) { return hook; } diff --git a/packages/solutions/module-tools/src/builder/esbuild/index.ts b/packages/solutions/module-tools/src/builder/esbuild/index.ts new file mode 100644 index 000000000000..ca8ae76254be --- /dev/null +++ b/packages/solutions/module-tools/src/builder/esbuild/index.ts @@ -0,0 +1,295 @@ +import { + BuildResult, + BuildOptions, + BuildContext, + context, + build, + OnLoadArgs, + ImportKind, + formatMessages, + Format, +} from 'esbuild'; +import * as tapable from 'tapable'; +import { FSWatcher, chalk, logger, fs, lodash } from '@modern-js/utils'; +import { + BaseBuildConfig, + BuilderHooks, + Chunk, + ICompiler, + LoadResult, + ModuleTools, + PluginAPI, + Context, + HookList, +} from '../../types'; +import { getInternalList } from '../feature'; +import { cssExtensions } from '../../constants/build'; +import { adapterPlugin } from './adapter'; +import { TransformContext } from './transform'; +import { SourcemapContext } from './sourcemap'; +import { createRenderChunkHook, createTransformHook } from './hook'; +import { createResolver } from './resolve'; + +export class EsbuildCompiler implements ICompiler { + instance?: BuildContext; + + result?: BuildResult; + + hookList?: HookList; + + reBuildCount: number; + + buildOptions: BuildOptions; + + context: Context; + + config: BaseBuildConfig; + + hooks: BuilderHooks; + + api: PluginAPI; + + outputChunk: Map = new Map(); + + watchedFiles: Set = new Set(); + + css_resolve: (id: string, dir: string) => string; + + node_resolve: (id: string, dir: string, kind: ImportKind) => string; + + watcher?: FSWatcher; + + virtualModule: Map = new Map(); + + private transformContextMap: Map = new Map(); + + private sourcemapContextMap: Map = new Map(); + + constructor(context: Context) { + const { api, config, root } = context; + this.reBuildCount = 0; + this.context = context; + this.api = api; + this.config = config; + this.buildOptions = this.convertConfigToEsbuild(config); + this.hooks = Object.freeze({ + load: new tapable.AsyncSeriesBailHook< + [OnLoadArgs], + LoadResult | undefined | void + >(['loadArgs']), + transform: createTransformHook(this), + renderChunk: createRenderChunkHook(this), + }); + const resolveOptions = { + root, + platform: config.platform, + alias: config.alias, + tsconfig: config.tsconfig, + mainFields: config.resolve.mainFields, + }; + this.css_resolve = createResolver({ + ...resolveOptions, + resolveType: 'css', + extensions: cssExtensions, + preferRelative: true, + }); + this.node_resolve = createResolver({ + ...resolveOptions, + resolveType: 'js', + extensions: config.resolve.jsExtensions, + }); + } + + async init() { + const internal = await getInternalList(this.context); + const user = this.config.hooks; + this.hookList = [...user, ...internal]; + await Promise.all(this.hookList.map(item => item.apply(this))); + } + + addWatchFile(id: string): void { + if (!this.watchedFiles.has(id)) { + this.watcher?.add?.(id); + this.watchedFiles.add(id); + } + } + + convertConfigToEsbuild(config: BaseBuildConfig): BuildOptions { + const { + input, + buildType, + define, + target, + sourceMap, + platform, + splitting, + outDir, + sourceDir, + minify, + jsx, + esbuildOptions, + format, + asset, + tsconfig, + banner, + footer, + } = config; + + const bundle = buildType === 'bundle'; + const entryNames = bundle ? '[name]' : '[dir]/[name]'; + const absWorkingDir = this.context.root; + let esbuildFormat: Format = format === 'umd' ? 'esm' : format; + if (bundle && format === 'cjs' && splitting) { + esbuildFormat = 'esm'; + } + const esbuildTarget = target === 'es5' ? undefined : target; + const jsExtensions = ['.jsx', '.tsx', '.js', '.ts', '.json']; + + const buildOptions: BuildOptions = { + banner: lodash.pick(banner, ['js', 'css']), + footer: lodash.pick(footer, ['js', 'css']), + entryPoints: input, + metafile: true, + define, + bundle: buildType === 'bundle', + format: esbuildFormat, + target: esbuildTarget, + sourcemap: sourceMap ? 'external' : false, + resolveExtensions: jsExtensions, + splitting, + charset: 'utf8', + logLimit: 5, + absWorkingDir, + platform, + tsconfig: fs.existsSync(tsconfig) ? tsconfig : undefined, + write: false, + logLevel: 'silent', + outdir: outDir, + outbase: sourceDir, + entryNames, + plugins: [adapterPlugin(this)], + minify: minify === 'esbuild', + jsx, + supported: { + 'dynamic-import': buildType === 'bundle' || format !== 'cjs', + }, + assetNames: `${asset.path}/[name].[hash]`, + }; + return esbuildOptions(buildOptions); + } + + getTransformContext(path: string): TransformContext { + if (this.transformContextMap.has(path)) { + return this.transformContextMap.get(path)!; + } + const context: TransformContext = new TransformContext( + Boolean(this.context.config.sourceMap), + ); + this.transformContextMap.set(path, context); + return context; + } + + getSourcemapContext(path: string): SourcemapContext { + if (this.sourcemapContextMap.has(path)) { + return this.sourcemapContextMap.get(path)!; + } + const context: SourcemapContext = new SourcemapContext( + Boolean(this.context.config.sourceMap), + ); + this.sourcemapContextMap.set(path, context); + return context; + } + + emitAsset(name: string, chunk: string | Chunk) { + if (typeof chunk === 'string') { + this.outputChunk.set(name, { + type: 'asset', + contents: chunk, + fileName: name, + }); + } else { + this.outputChunk.set(name, chunk); + } + } + + async close() { + try { + await this.instance?.cancel(); + await this.instance?.dispose(); + } catch (err) {} + } + + async build() { + const { + buildOptions, + context: { watch }, + } = this; + try { + if (watch) { + this.instance = await context(buildOptions); + this.result = await this.instance.rebuild(); + } else { + this.result = await build(buildOptions); + } + if (this.result.warnings.length) { + const warnings = this.result.warnings.filter(warning => { + // filter all warnings that are related to "require" + if ( + warning.text.includes( + `This call to "require" will not be bundled because`, + ) || + warning.text.includes( + `Indirect calls to "require" will not be bundled`, + ) || + warning.text.includes( + `Converting "require" to "esm" is currently not supported`, + ) + ) { + return false; + } + + return true; + }); + + const messages = await formatMessages(warnings, { + kind: 'warning', + }); + + messages.forEach(m => { + logger.warn(m); + }); + } + } catch (error: any) { + if (watch) { + this.instance?.cancel(); + logger.error(error); + } else { + throw error; + } + } + } + + async reBuild(type: 'link' | 'change') { + const { instance } = this; + try { + const start = Date.now(); + if (type === 'link') { + await this.build(); + } else { + this.result = await instance?.rebuild(); + } + logger.info( + chalk.green`Rebuild Successfully in ${Date.now() - start}ms`, + chalk.yellow`Rebuild Count: ${++this.reBuildCount}`, + ); + } catch (error: any) { + logger.error(error); + } + } +} + +export const createCompiler = async (context: Context) => { + const compiler = new EsbuildCompiler(context); + await compiler.init(); + return compiler; +}; diff --git a/packages/solutions/module-tools/src/builder/esbuild/resolve.ts b/packages/solutions/module-tools/src/builder/esbuild/resolve.ts new file mode 100644 index 000000000000..2691f5797504 --- /dev/null +++ b/packages/solutions/module-tools/src/builder/esbuild/resolve.ts @@ -0,0 +1,101 @@ +import fs from 'fs'; +import { CachedInputFileSystem, create } from 'enhanced-resolve'; +import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; +import { ImportKind, Platform } from 'esbuild'; + +/** + * supports require js plugin in less file + */ +export const cssExtensions = ['.less', '.css', '.sass', '.scss', '.js']; + +function createEnhancedResolve(options: ResolverOptions): { + resolveSync: (dir: string, id: string) => string | false; + esmResolveSync: (dir: string, id: string) => string | false; +} { + const plugins = []; + const { tsconfig } = options; + + // tsconfig-paths directly statSync `tsconfig.json` without confirm it's exist. + if (fs.existsSync(tsconfig)) { + plugins.push( + new TsconfigPathsPlugin({ + baseUrl: options.root, + configFile: tsconfig, + }), + ); + } + const resolveOptions = { + aliasFields: options.platform === 'browser' ? ['browser'] : [], + FileSystem: new CachedInputFileSystem(fs, 4000), + mainFields: options.mainFields, + mainFiles: ['index'], + extensions: options.extensions, + preferRelative: options.preferRelative, + addMatchAll: false, + plugins, + alias: options.alias, + }; + + // conditionNames follow webpack options + // cjs + const resolveSync = (dir: string, id: string) => + create.sync({ + ...resolveOptions, + conditionNames: [options.platform, 'require', 'module'], + })(dir, id); + + const esmResolveSync = (dir: string, id: string) => + create.sync({ + ...resolveOptions, + conditionNames: [options.platform, 'import', 'module'], + })(dir, id); + + return { + resolveSync, + esmResolveSync, + }; +} + +export const createResolver = (options: ResolverOptions) => { + const resolveCache = new Map(); + const { resolveSync, esmResolveSync } = createEnhancedResolve(options); + const resolver = (id: string, dir: string, kind?: ImportKind) => { + const cacheKey = id + dir + (kind || ''); + const cacheResult = resolveCache.get(cacheKey); + + if (cacheResult) { + return cacheResult; + } + let result: string | false; + if (options.resolveType === 'js') { + if (kind === 'import-statement' || kind === 'dynamic-import') { + result = esmResolveSync(dir, id); + } else { + result = resolveSync(dir, id); + } + } else { + try { + result = resolveSync(dir, id); + } catch (err) { + result = resolveSync(dir, id.replace(/^~/, '')); + } + } + if (!result) { + throw new Error(`can not resolve ${id} from ${dir}`); + } + resolveCache.set(cacheKey, result); + return result; + }; + return resolver; +}; + +interface ResolverOptions { + platform: Platform; + resolveType: 'js' | 'css'; + extensions: string[]; + root: string; + alias: Record; + tsconfig: string; + mainFields: string[]; + preferRelative?: boolean; +} diff --git a/packages/libuild/libuild-core/src/core/sourcemap.ts b/packages/solutions/module-tools/src/builder/esbuild/sourcemap.ts similarity index 92% rename from packages/libuild/libuild-core/src/core/sourcemap.ts rename to packages/solutions/module-tools/src/builder/esbuild/sourcemap.ts index ed955e0a4ca1..177cc5dda441 100644 --- a/packages/libuild/libuild-core/src/core/sourcemap.ts +++ b/packages/solutions/module-tools/src/builder/esbuild/sourcemap.ts @@ -1,5 +1,5 @@ -import { SourceMap, ISourcemapContext } from '../types'; -import { mergeMaps } from '../utils/remapping'; +import { SourceMap, ISourcemapContext } from '../../types'; +import { mergeMaps } from '../../utils'; export class SourcemapContext implements ISourcemapContext { private sourceMapChain: (SourceMap | undefined)[] = []; @@ -22,7 +22,6 @@ export class SourcemapContext implements ISourcemapContext { if (this.enableSourceMap && this.sourceMapChain[pluginId] !== map) { this.sourceMapChain[pluginId] = map; this.markSourceMapStatus(true); - // console.log('sourcemap dirty') } } diff --git a/packages/solutions/module-tools/src/builder/esbuild/transform.ts b/packages/solutions/module-tools/src/builder/esbuild/transform.ts new file mode 100644 index 000000000000..4104e410d0e8 --- /dev/null +++ b/packages/solutions/module-tools/src/builder/esbuild/transform.ts @@ -0,0 +1,24 @@ +import { ITransformContext, CacheValue } from '../../types'; +import { SourcemapContext } from './sourcemap'; + +export class TransformContext + extends SourcemapContext + implements ITransformContext +{ + private cachedTransformResult: Map = new Map< + number, + CacheValue + >(); + + public addTransformResult(pluginId: number, result: CacheValue) { + this.cachedTransformResult.set(pluginId, result); + this.addSourceMap(pluginId, result.map); + } + + public getValidCache(pluginId: number, code: string) { + const cache = this.cachedTransformResult.get(pluginId); + if (cache && cache.originCode === code) { + return cache; + } + } +} diff --git a/packages/solutions/module-tools/src/builder/esbuild/watch.ts b/packages/solutions/module-tools/src/builder/esbuild/watch.ts new file mode 100644 index 000000000000..5ff331d6b9d9 --- /dev/null +++ b/packages/solutions/module-tools/src/builder/esbuild/watch.ts @@ -0,0 +1,93 @@ +import type { Stats } from 'fs'; +import path from 'path'; +import { chalk, logger, chokidar } from '@modern-js/utils'; +import { ICompiler } from '../../types'; + +export const initWatcher = (compiler: ICompiler) => { + const { config, api } = compiler; + const watch = chokidar.watch([compiler.context.root], { + useFsEvents: false, // disable fsevents due to fsevents hoist problem + ignored: [ + '**/node_modules', + '**/.gitignore', + '**/.git', + compiler.config.outDir, + ], + cwd: compiler.context.root, + }); + compiler.watcher = watch; + let running = false; + let needReRun = false; + + const handleLink = async (filePath: string, type: 'add' | 'unlink') => { + const { + config, + context: { root }, + } = compiler; + const { buildType, input, sourceDir } = config; + const absFilePath = path.resolve(root, filePath); + let shouldRebuild = false; + if (buildType === 'bundleless' && Array.isArray(input)) { + if (type === 'add') { + shouldRebuild = absFilePath.startsWith(sourceDir); + } else { + shouldRebuild = input.some(item => item === filePath); + } + } + if (shouldRebuild) { + const text = type === 'add' ? 'added' : 'unlinked'; + logger.info(`${chalk.underline(filePath)} ${text}`); + if (type === 'unlink') { + (input as string[]).splice((input as string[]).indexOf(filePath), 1); + } else { + (input as string[]).push(filePath); + } + if (running) { + needReRun = true; + } else { + running = true; + await compiler.reBuild('link'); + running = false; + if (needReRun) { + needReRun = false; + await compiler.reBuild('link'); + } + } + } + }; + const handleAdd = async (filePath: string) => { + return handleLink(filePath, 'add'); + }; + const handleUnlink = async (filePath: string) => { + return handleLink(filePath, 'unlink'); + }; + + const handleChange = async (filePath: string, _events: Stats) => { + const { + context: { root }, + watchedFiles, + } = compiler; + if (watchedFiles.has(path.resolve(root, filePath))) { + logger.info(`${chalk.underline(filePath)} changed`); + const { watchSectionTitle } = await import('../../utils'); + const { SectionTitleStatus } = await import('../../constants/log'); + const titleText = `[${ + config.buildType === 'bundle' ? 'Bundle' : 'Bundleless' + }:${config.format}_${config.target}]`; + + logger.info(await watchSectionTitle(titleText, SectionTitleStatus.Log)); + + const runner = api.useHookRunners(); + runner.buildWatchJs({ buildConfig: config }); + await compiler.reBuild('change'); + } + }; + watch.on('ready', () => { + watch.on('change', handleChange); + watch.on('add', handleAdd); + watch.on('unlink', handleUnlink); + }); + watch.once('restart', () => { + watch.removeListener('change', handleChange); + }); +}; diff --git a/packages/solutions/module-tools/src/builder/esbuild/write-file.ts b/packages/solutions/module-tools/src/builder/esbuild/write-file.ts new file mode 100644 index 000000000000..f08c46f0d423 --- /dev/null +++ b/packages/solutions/module-tools/src/builder/esbuild/write-file.ts @@ -0,0 +1,69 @@ +import path from 'path'; +import { fs } from '@modern-js/utils'; +import convertSourceMap from 'convert-source-map'; +import { Chunk, ICompiler } from '../../types'; + +const SOURCE_MAPPING_URL = 'sourceMappingURL'; +let preOutputChunk: Map | null = null; + +function appendSourceMapURLLink(options: { filename: string; code: string }) { + return `${options.code}\n//# ${SOURCE_MAPPING_URL}=${options.filename}.map`; +} + +function appendSourceMapInline(options: { map: string; code: string }) { + return `${options.code}\n//# ${SOURCE_MAPPING_URL}=data:application/json;charset=utf-8;base64,${options.map}`; +} + +function chunkHasChanged(key: string, chunk: Chunk) { + if (preOutputChunk) { + const preChunk = preOutputChunk.get(key); + if (preChunk && preChunk.contents === chunk.contents) { + return false; + } + } + return true; +} + +export const writeFile = async (compiler: ICompiler) => { + for (const [key, value] of compiler.outputChunk.entries()) { + if (!chunkHasChanged(key, value)) { + continue; + } + const absPath = path.resolve(compiler.config.outDir, key); + await fs.ensureDir(path.dirname(absPath)); + if (value.type === 'chunk' && value.map) { + if ( + compiler.config.sourceMap === false || + compiler.config.sourceMap === 'external' + ) { + await fs.writeFile(absPath, value.contents); + } else if (compiler.config.sourceMap === true) { + await fs.writeFile( + absPath, + appendSourceMapURLLink({ + code: value.contents, + filename: path.basename(absPath), + }), + ); + } else if (compiler.config.sourceMap === 'inline') { + await fs.writeFile( + absPath, + appendSourceMapInline({ + code: value.contents, + map: convertSourceMap.fromObject(value.map).toBase64(), + }), + ); + } + + if ( + compiler.config.sourceMap === true || + compiler.config.sourceMap === 'external' + ) { + await fs.writeFile(`${absPath}.map`, JSON.stringify(value.map)); + } + } else { + await fs.writeFile(absPath, value.contents); + } + } + preOutputChunk = compiler.outputChunk; +}; diff --git a/packages/solutions/module-tools/src/builder/feature/asset.ts b/packages/solutions/module-tools/src/builder/feature/asset.ts new file mode 100644 index 000000000000..edfd659d08ec --- /dev/null +++ b/packages/solutions/module-tools/src/builder/feature/asset.ts @@ -0,0 +1,160 @@ +import { basename, join, extname, relative, dirname, resolve } from 'path'; +import fs from 'fs'; +import type { Loader } from 'esbuild'; +import { createFilter } from '@rollup/pluginutils'; +import { transform } from '@svgr/core'; +import svgo from '@svgr/plugin-svgo'; +import jsx from '@svgr/plugin-jsx'; +import { ICompiler, LoadResult, SvgrOptions } from '../../types'; +import { assetExt } from '../../constants/file'; +import { normalizeSlashes, getHash } from '../../utils'; + +const name = 'asset'; +const SVG_REGEXP = /\.svg$/; + +export const asset = { + name, + apply(compiler: ICompiler) { + compiler.hooks.load.tapPromise({ name }, async args => { + if (assetExt.find(ext => ext === extname(args.path))) { + const { buildType, outDir, sourceDir, asset } = compiler.config; + + const svgrResult = await loadSvgr(args.path, asset.svgr); + if (svgrResult) { + return svgrResult; + } + + const rebaseFrom = + buildType === 'bundle' + ? outDir + : join(outDir, relative(sourceDir, dirname(args.path))); + + const { contents, loader } = await getAssetContents.apply(compiler, [ + args.path, + rebaseFrom, + true, + ]); + return { + contents, + loader, + }; + } + }); + }, +}; + +// https://github.com/filamentgroup/directory-encoder/blob/master/lib/svg-uri-encoder.js +function encodeSVG(buffer: Buffer) { + return ( + encodeURIComponent( + buffer + .toString('utf-8') + // strip newlines and tabs + .replace(/[\n\r]/gim, '') + .replace(/\t/gim, ' ') + // strip comments + .replace(/))-->/gim, '') + // replace + .replace(/'/gim, '\\i'), + ) + // encode brackets + .replace(/\(/g, '%28') + .replace(/\)/g, '%29') + ); +} + +/** + * + * @param this Compiler + * @param assetPath Absolute path of the asset + * @param rebaseFrom Absolute path of the file which use asset + * @param calledOnLoad called in load hooks + * @returns dataurl or path + */ +export async function getAssetContents( + this: ICompiler, + assetPath: string, + rebaseFrom: string, + calledOnLoad?: boolean, +) { + const fileContent = await fs.promises.readFile(assetPath); + const { buildType, format, outDir } = this.config; + const { limit, path, publicPath } = this.config.asset; + const hash = getHash(fileContent, null).slice(0, 8); + + const outputFileName = basename(assetPath).split('.').join(`.${hash}.`); + const outputFilePath = resolve(outDir, path, outputFileName); + const relativePath = relative(rebaseFrom, outputFilePath); + const normalizedRelativePath = normalizeSlashes( + relativePath.startsWith('..') ? relativePath : `./${relativePath}`, + ); + const normalizedPublicPath = `${ + typeof publicPath === 'function' ? publicPath(assetPath) : publicPath + }${path}/${outputFileName}`; + + let emitAsset = true; + let contents: string | Buffer = normalizedPublicPath; + let loader: Loader = 'text'; + if (buildType === 'bundle') { + // inline base64 + if (fileContent.length <= limit) { + const mimetype = (await import('mime-types')).default.lookup(assetPath); + const isSVG = mimetype === 'image/svg+xml'; + const data = isSVG + ? encodeSVG(fileContent) + : fileContent.toString('base64'); + const encoding = isSVG ? '' : ';base64'; + contents = `data:${mimetype}${encoding},${data}`; + loader = 'text'; + emitAsset = false; + } else if ((format === 'esm' || format === 'cjs') && !publicPath) { + contents = calledOnLoad ? fileContent : normalizedRelativePath; + loader = calledOnLoad ? 'copy' : 'text'; + emitAsset = !calledOnLoad; + } + } else { + // bundleless + contents = normalizedRelativePath; + } + if (emitAsset) { + this.emitAsset(outputFilePath, { + type: 'asset', + fileName: outputFilePath, + contents: fileContent, + originalFileName: assetPath, + }); + } + return { + contents, + loader, + }; +} + +export async function loadSvgr( + path: string, + options: boolean | SvgrOptions, +): Promise { + if (!options) { + return; + } + + const config = typeof options === 'boolean' ? {} : options; + + const filter = createFilter(config.include || SVG_REGEXP, config.exclude); + if (!filter(path)) { + return; + } + const loader = 'jsx'; + const text = fs.readFileSync(path, 'utf8'); + const jsCode = await transform(text, config, { + filePath: path, + caller: { + name: 'svgr', + defaultPlugins: [svgo, jsx], + }, + }); + return { + contents: jsCode, + loader, + }; +} diff --git a/packages/solutions/module-tools/src/builder/feature/format-cjs.ts b/packages/solutions/module-tools/src/builder/feature/format-cjs.ts new file mode 100644 index 000000000000..05db1e15980f --- /dev/null +++ b/packages/solutions/module-tools/src/builder/feature/format-cjs.ts @@ -0,0 +1,25 @@ +import { transform } from 'sucrase'; +import { ICompiler } from '../../types'; + +const name = 'format-cjs'; +const apply = (compiler: ICompiler) => { + compiler.hooks.renderChunk.tapPromise({ name }, async chunk => { + if (chunk.fileName.endsWith('.js') && chunk.type === 'chunk') { + const code = chunk.contents.toString(); + const result = transform(code, { + transforms: ['imports'], + }); + return { + ...chunk, + contents: result.code, + map: result.sourceMap, + }; + } + return chunk; + }); +}; + +export const formatCjs = { + name, + apply, +}; diff --git a/packages/solutions/module-tools/src/builder/feature/index.ts b/packages/solutions/module-tools/src/builder/feature/index.ts new file mode 100644 index 000000000000..f5104bab3d19 --- /dev/null +++ b/packages/solutions/module-tools/src/builder/feature/index.ts @@ -0,0 +1,58 @@ +import { HookList, Context } from '../../types'; +import { getProjectTsconfig } from '../../utils/dts'; +import { formatCjs } from './format-cjs'; +import { css } from './style'; +import { minify } from './terser'; +import { asset } from './asset'; + +export async function getInternalList(context: Context): Promise { + const internal = []; + const { config } = context; + + internal.push(asset, css); + + if ( + config.buildType === 'bundle' && + config.format === 'cjs' && + config.splitting + ) { + internal.push(formatCjs); + } + + if (config.buildType === 'bundleless') { + const { redirect } = await import('./redirect'); + const { json } = await import('./json'); + internal.push(redirect, json); + } + + if (config.minify && config.minify !== 'esbuild') { + internal.push(minify); + } + + const userTsconfig = await getProjectTsconfig(context.config.tsconfig); + const emitDecoratorMetadata = + userTsconfig?.compilerOptions?.emitDecoratorMetadata ?? false; + + const { transformImport, transformLodash, externalHelpers, format, target } = + context.config; + + const enbaleSwcTransform = + transformImport.length > 0 || + transformLodash || + externalHelpers || + emitDecoratorMetadata; + const enableSwcRenderChunk = enbaleSwcTransform + ? format === 'umd' + : format === 'umd' || target === 'es5'; + if (enbaleSwcTransform) { + const { swcTransform } = await import('./swc'); + internal.push(swcTransform(userTsconfig)); + } + + if (enableSwcRenderChunk) { + const { swcRenderChunk } = await import('./swc'); + internal.push(swcRenderChunk); + } + + return internal; +} diff --git a/packages/solutions/module-tools/src/builder/feature/json.ts b/packages/solutions/module-tools/src/builder/feature/json.ts new file mode 100644 index 000000000000..e820d5f34a64 --- /dev/null +++ b/packages/solutions/module-tools/src/builder/feature/json.ts @@ -0,0 +1,21 @@ +import { readFileSync } from 'fs'; +import { ICompiler } from '../../types'; + +const isJsonExt = (path: string) => { + return path.endsWith('.json'); +}; + +const name = 'json'; +export const json = { + name, + apply(compiler: ICompiler) { + compiler.hooks.load.tapPromise({ name }, async args => { + if (isJsonExt(args.path)) { + return { + contents: readFileSync(args.path), + loader: 'copy', + }; + } + }); + }, +}; diff --git a/packages/libuild/libuild-core/src/plugins/redirect.ts b/packages/solutions/module-tools/src/builder/feature/redirect.ts similarity index 52% rename from packages/libuild/libuild-core/src/plugins/redirect.ts rename to packages/solutions/module-tools/src/builder/feature/redirect.ts index 40ed676baa9a..171a1b8cb999 100644 --- a/packages/libuild/libuild-core/src/plugins/redirect.ts +++ b/packages/solutions/module-tools/src/builder/feature/redirect.ts @@ -8,24 +8,24 @@ import { relative, join, dirname, - win32, - basename, extname, + basename, } from 'path'; -import { init, parse } from 'es-module-lexer'; -import type { ImportSpecifier } from 'es-module-lexer'; import { js } from '@ast-grep/napi'; import MagicString from 'magic-string'; -import { resolvePathAndQuery } from '@modern-js/libuild-utils'; import { createMatchPath, loadConfig, MatchPath } from 'tsconfig-paths'; -import { ILibuilder, LibuildPlugin } from '../types'; -import { getAssetContents, assetExt } from './asset'; +import { fs, logger } from '@modern-js/utils'; +import { ICompiler } from '../../types'; +import { assetExt } from '../../constants/file'; +import { + normalizeSlashes, + isJsExt, + isJsLoader, + resolvePathAndQuery, +} from '../../utils'; +import { getAssetContents, loadSvgr } from './asset'; import { isCssModule } from './style/postcssTransformer'; -function normalizeSlashes(file: string) { - return file.split(win32.sep).join('/'); -} - type MatchModule = { name?: string; start: number; @@ -33,7 +33,7 @@ type MatchModule = { }[]; async function redirectImport( - compiler: ILibuilder, + compiler: ICompiler, code: string, modules: MatchModule, aliasRecord: Record, @@ -51,7 +51,8 @@ async function redirectImport( const { start, end } = module; let { name } = module; - const { alias, style, asset } = compiler.config.redirect; + const { redirect, asset } = compiler.config; + const { alias, style } = redirect; if (alias) { // redirect alias @@ -86,8 +87,8 @@ async function redirectImport( if (style) { // redirect style path - const { originalFilePath, query } = resolvePathAndQuery(name); const ext = extname(name); + const { originalFilePath, query } = resolvePathAndQuery(name); if (query.css_virtual) { // css module @@ -96,14 +97,14 @@ async function redirectImport( extname(originalFilePath), ).replace('.', '_'); const base = `${replacedName}.css`; - const contents = compiler.virtualModule.get(originalFilePath)!; + const key = query.hash as string; + const contents = compiler.virtualModule.get(key)!; const fileName = join(outputDir, base); compiler.emitAsset(fileName, { type: 'asset', contents, fileName, - originalFileName: originalFilePath, - entryPoint: originalFilePath, + originalFileName: name, }); const relativeImportPath = normalizeSlashes(`./${base}`); str.overwrite(start, end, relativeImportPath); @@ -129,11 +130,11 @@ async function redirectImport( } } - if (asset) { + if (redirect.asset) { if (assetExt.filter(ext => name.endsWith(ext)).length) { // asset const absPath = resolve(dirname(filePath), name); - const svgrResult = await compiler.loadSvgr(absPath); + const svgrResult = await loadSvgr(absPath, asset.svgr); if (svgrResult) { // svgr const ext = extname(name); @@ -153,104 +154,107 @@ async function redirectImport( } // base dir to redirect import path -export const redirectPlugin = (): LibuildPlugin => { - const pluginName = 'libuild:redirect'; - return { - name: pluginName, - apply(compiler) { - compiler.hooks.processAsset.tapPromise(pluginName, async args => { - if (args.type === 'asset') { - return args; - } - const { contents: code, fileName, entryPoint: id } = args; - const { - format, - resolve: { alias }, - } = compiler.config; - - if (!code || format === 'iife' || format === 'umd') { - return args; - } - - // transform alias to absolute path - const absoluteAlias = Object.entries(alias).reduce( - (result, [name, target]) => { - if (!isAbsolute(target)) { - result[name] = resolve(compiler.config.root, target); - } else { - result[name] = target; - } - return result; - }, - {}, +const name = 'redirect'; +export const redirect = { + name, + apply(compiler: ICompiler) { + // get matchPath func to support tsconfig paths + let matchPath: MatchPath | undefined; + if (fs.existsSync(compiler.config.tsconfig)) { + const result = loadConfig(compiler.config.tsconfig); + if (result.resultType === 'success') { + const { absoluteBaseUrl, paths, mainFields, addMatchAll } = result; + matchPath = createMatchPath( + absoluteBaseUrl, + paths, + mainFields, + addMatchAll, ); + } + } + compiler.hooks.transform.tapPromise({ name }, async args => { + if (!isJsExt(args.path) && !isJsLoader(args.loader)) { + return args; + } + const { code, path: id } = args; + const { format, alias, sourceDir, outDir } = compiler.config; - // get matchPath func to support tsconfig paths - const result = loadConfig(compiler.config.root); - let matchPath: MatchPath | undefined; - if (result.resultType === 'success') { - const { absoluteBaseUrl, paths, mainFields, addMatchAll } = result; - matchPath = createMatchPath( - absoluteBaseUrl, - paths, - mainFields, - addMatchAll, - ); - } + if (!code || format === 'iife' || format === 'umd') { + return args; + } - let matchModule: MatchModule = []; - if (format === 'esm') { - await init; - let imports: readonly ImportSpecifier[] = []; - try { - [imports] = parse(code); - } catch (e) { - console.error('[parse error]', e); + // transform alias to absolute path + const absoluteAlias = Object.entries(alias).reduce( + (result, [name, target]) => { + if (!isAbsolute(target)) { + result[name] = resolve(compiler.context.root, target); + } else { + result[name] = target; } - matchModule = imports.map(targetImport => { + return result; + }, + {}, + ); + + let matchModule: MatchModule = []; + try { + const sgNode = js.parse(code).root(); + const funcPattern = [`require($MATCH)`, `import($MATCH)`]; + const staticPattern = [ + `import $$VAR from '$MATCH'`, + `import $$VAR from "$MATCH"`, + `import '$MATCH'`, + `import "$MATCH"`, + ]; + const funcMatchModule = funcPattern + .map(p => { + return sgNode.findAll(p); + }) + .flat() + .map(node => { + const matchNode = node.getMatch('MATCH')!; return { - name: targetImport.n, - start: targetImport.s, - end: targetImport.e, + name: matchNode.text().slice(1, -1), + start: matchNode.range().start.index + 1, + end: matchNode.range().end.index - 1, }; }); - } - if (format === 'cjs') { - try { - const sgNode = js.parse(code).root(); - matchModule = sgNode.findAll('require($MATCH)').map(node => { - const matchNode = node.getMatch('MATCH')!; - return { - name: matchNode.text().slice(1, -1), - start: matchNode.range().start.index + 1, - end: matchNode.range().end.index - 1, - }; - }); - } catch (e) { - console.error('[parse error]', e); - } - } - if (!matchModule.length) { - return args; - } - const str = await redirectImport( - compiler, - code, - matchModule, - absoluteAlias, - id!, - dirname(fileName), - matchPath, - ); - return { - ...args, - contents: str.toString(), - map: str.generateMap({ - hires: true, - includeContent: true, - }), - }; - }); - }, - }; + const staticMatchModule = staticPattern + .map(p => sgNode.findAll(p)) + .flat() + .map(node => { + const matchNode = node.getMatch('MATCH')!; + return { + name: matchNode.text(), + start: matchNode.range().start.index, + end: matchNode.range().end.index, + }; + }); + matchModule = [...funcMatchModule, ...staticMatchModule]; + } catch (e) { + logger.error('[parse error]', e); + } + if (!matchModule.length) { + return args; + } + const outputPath = resolve(outDir, relative(sourceDir, id)); + const str = await redirectImport( + compiler, + code, + matchModule, + absoluteAlias, + id, + dirname(outputPath), + matchPath, + ); + return { + ...args, + code: str.toString(), + map: str.generateMap({ + hires: true, + includeContent: true, + }), + }; + }); + }, }; diff --git a/packages/solutions/module-tools/src/builder/feature/style/index.ts b/packages/solutions/module-tools/src/builder/feature/style/index.ts new file mode 100644 index 000000000000..a38fefd65e89 --- /dev/null +++ b/packages/solutions/module-tools/src/builder/feature/style/index.ts @@ -0,0 +1,59 @@ +import { readFileSync } from 'fs'; +import { identifier } from 'safe-identifier'; +import { isStyleExt, resolvePathAndQuery } from '../../../utils'; +import { Source, ICompiler } from '../../../types'; +import { transformStyle } from './transformStyle'; + +const name = 'css'; +export const css = { + name, + apply(compiler: ICompiler) { + compiler.hooks.load.tapPromise({ name }, async args => { + if (isStyleExt(args.path)) { + const { query } = resolvePathAndQuery(args.path); + + if (query?.css_virtual) { + const key = query.hash as string; + const contents = compiler.virtualModule.get(key)!; + return { + contents, + loader: 'css', + }; + } + return { + contents: readFileSync(args.path), + loader: 'css', + }; + } + }); + compiler.hooks.transform.tapPromise( + { name }, + async (source): Promise => { + if (isStyleExt(source.path)) { + let { code, loader = 'css' } = source; + const { query } = resolvePathAndQuery(source.path); + if (!query?.css_virtual) { + ({ code, loader } = await transformStyle.apply(compiler, [source])); + } + const { style, buildType } = compiler.config; + if (style.inject && buildType === 'bundle' && loader === 'css') { + const styleInjectPath = require + .resolve('style-inject/dist/style-inject.es') + .replace(/[\\/]+/g, '/'); + const cssVariableName = identifier('css', true); + code = `var ${cssVariableName} = ${JSON.stringify( + code, + )};\nimport styleInject from '${styleInjectPath}';\nstyleInject(${cssVariableName});`; + loader = 'js'; + } + return { + ...source, + code, + loader, + }; + } + return source; + }, + ); + }, +}; diff --git a/packages/libuild/libuild-core/src/plugins/style/lessAliasPlugin.ts b/packages/solutions/module-tools/src/builder/feature/style/lessAliasPlugin.ts similarity index 75% rename from packages/libuild/libuild-core/src/plugins/style/lessAliasPlugin.ts rename to packages/solutions/module-tools/src/builder/feature/style/lessAliasPlugin.ts index 47d0ca6dfef2..b1224b07090a 100644 --- a/packages/libuild/libuild-core/src/plugins/style/lessAliasPlugin.ts +++ b/packages/solutions/module-tools/src/builder/feature/style/lessAliasPlugin.ts @@ -1,34 +1,35 @@ import fs from 'fs'; +import { ICompiler } from '../../../types'; import { rebaseUrls } from './utils'; interface Options { - config: any; + compiler: ICompiler; stdinDir: string; } export default class LessAliasesPlugin { - config: any; + compiler: ICompiler; stdinDir: string; constructor(options: Options) { - this.config = options.config; + this.compiler = options.compiler; this.stdinDir = options.stdinDir; } install(less: any, pluginManager: any) { const getResolve = (filename: string, currentDirectory: string) => { - return this.config.css_resolve( + return this.compiler.css_resolve( filename, currentDirectory || this.stdinDir, ); }; class AliasPlugin extends less.FileManager { - config: any; + compiler: ICompiler; constructor(options: Options) { super(); - this.config = options.config; + this.compiler = options.compiler; this.stdinDir = options.stdinDir; } @@ -37,7 +38,7 @@ export default class LessAliasesPlugin { const rebasedContents = await rebaseUrls( resolved, this.stdinDir, - this.config.css_resolve, + this.compiler.css_resolve, ); const contents = rebasedContents.contents ? rebasedContents.contents @@ -50,7 +51,7 @@ export default class LessAliasesPlugin { } } pluginManager.addFileManager( - new AliasPlugin({ config: this.config, stdinDir: this.stdinDir }), + new AliasPlugin({ compiler: this.compiler, stdinDir: this.stdinDir }), ); } } diff --git a/packages/libuild/libuild-core/src/plugins/style/lessRender.ts b/packages/solutions/module-tools/src/builder/feature/style/lessRender.ts similarity index 75% rename from packages/libuild/libuild-core/src/plugins/style/lessRender.ts rename to packages/solutions/module-tools/src/builder/feature/style/lessRender.ts index 4ac17c1a977e..c023d533573b 100644 --- a/packages/libuild/libuild-core/src/plugins/style/lessRender.ts +++ b/packages/solutions/module-tools/src/builder/feature/style/lessRender.ts @@ -1,10 +1,11 @@ -import { ILibuilder } from '../../types'; +import { ICompiler } from '../../../types'; +import Less from '../../../../compiled/less'; import { loadProcessor } from './utils'; import { PreprocessRender } from './transformStyle'; import LessAliasesPlugin from './lessAliasPlugin'; export const lessRender: PreprocessRender = async function ( - this: ILibuilder, + this: ICompiler, content: string, originPath: string, stdinDir: string, @@ -12,7 +13,7 @@ export const lessRender: PreprocessRender = async function ( _: Map, implementation?: object | string, ) { - const less = await loadProcessor('less', this.config.root, implementation); + const less = await loadProcessor('less', this.context.root, implementation); const result = { ...(await less.render(content, { relativeUrls: true, @@ -20,12 +21,12 @@ export const lessRender: PreprocessRender = async function ( ...options, paths: [ ...(options?.paths || ['node_modules']), - this.config.root, + this.context.root, stdinDir, ], plugins: [ new LessAliasesPlugin({ - config: this.config, + compiler: this, stdinDir, }), ...(options?.plugins || []), diff --git a/packages/libuild/libuild-core/src/plugins/style/postcssTransformer.ts b/packages/solutions/module-tools/src/builder/feature/style/postcssTransformer.ts similarity index 58% rename from packages/libuild/libuild-core/src/plugins/style/postcssTransformer.ts rename to packages/solutions/module-tools/src/builder/feature/style/postcssTransformer.ts index aadfea9f1a39..042938d95f8c 100644 --- a/packages/libuild/libuild-core/src/plugins/style/postcssTransformer.ts +++ b/packages/solutions/module-tools/src/builder/feature/style/postcssTransformer.ts @@ -1,41 +1,8 @@ -import { deepMerge } from '@modern-js/libuild-utils'; import postcss from 'postcss'; -import postcssrc from 'postcss-load-config'; -import { DEFAULT_NODE_ENV } from '../../constants/config'; -import { ILibuilder, PostcssOptions, Style } from '../../types'; +import { ICompiler } from '../../../types'; +import { getHash, normalizeSlashes } from '../../../utils'; import { postcssUrlPlugin } from './postcssUrlPlugin'; -import { getHash } from './utils'; -async function loadPostcssConfig( - root: string, - postcssOptions: Style['postcss'], -): Promise { - let resolvedPostcssConfig: postcssrc.Result | null = null; - const options = postcssOptions ?? {}; - try { - resolvedPostcssConfig = await postcssrc( - { - env: process.env.NODE_ENV || DEFAULT_NODE_ENV, - }, - root, - ); - } catch (e) { - if (!/No PostCSS Config found/.test((e as Error)?.message)) { - throw e; - } - resolvedPostcssConfig = null; - } - if (resolvedPostcssConfig) { - return deepMerge( - { - processOptions: resolvedPostcssConfig.options, - plugins: resolvedPostcssConfig.plugins, - }, - options, - ); - } - return options; -} const cssLangs = `\\.(css|less|sass|scss)($|\\?)`; const cssModuleRE = new RegExp(`\\.module${cssLangs}`); @@ -51,15 +18,12 @@ export const isCssModule = ( export const postcssTransformer = async ( css: string, entryPath: string, - compilation: ILibuilder, + compilation: ICompiler, ): Promise<{ code: string; loader: 'js' | 'css'; }> => { - const postcssConfig = await loadPostcssConfig( - compilation.config.root, - compilation.config.style.postcss, - ); + const postcssConfig = compilation.config.style.postcss; const { plugins = [], processOptions = {} } = postcssConfig; const { modules: modulesOption = {}, autoModules = true } = compilation.config.style; @@ -103,12 +67,12 @@ export const postcssTransformer = async ( }); if (Object.values(modules).length) { // add hash query for same path, let esbuild cache invalid - compilation.virtualModule.set(entryPath, code); - const doubleBackslashesPath = entryPath.replace(/\\/g, '\\\\'); - code = `import "${doubleBackslashesPath}?css_virtual&hash=${getHash( - code, - 'utf-8', - )}";export default ${JSON.stringify(modules)}`; + const normalizedPath = normalizeSlashes(entryPath); + const key = getHash(code, 'utf-8').slice(0, 5); + compilation.virtualModule.set(key, code); + code = `import "${normalizedPath}?css_virtual&hash=${key}";export default ${JSON.stringify( + modules, + )}`; loader = 'js'; } diff --git a/packages/libuild/libuild-core/src/plugins/style/postcssUrlPlugin.ts b/packages/solutions/module-tools/src/builder/feature/style/postcssUrlPlugin.ts similarity index 73% rename from packages/libuild/libuild-core/src/plugins/style/postcssUrlPlugin.ts rename to packages/solutions/module-tools/src/builder/feature/style/postcssUrlPlugin.ts index d6ba938dc42e..95ad2624f44b 100644 --- a/packages/libuild/libuild-core/src/plugins/style/postcssUrlPlugin.ts +++ b/packages/solutions/module-tools/src/builder/feature/style/postcssUrlPlugin.ts @@ -1,6 +1,6 @@ import { join, relative, dirname } from 'path'; import { Plugin } from 'postcss'; -import { ILibuilder } from '../../types'; +import { ICompiler } from '../../../types'; import { getAssetContents } from '../asset'; import { rewriteCssUrls } from './utils'; @@ -11,12 +11,10 @@ const HASH_PATTERNS = /#[^#]+$/; export const postcssUrlPlugin = (options: { entryPath: string; - compilation: ILibuilder; -}) => { - options = options || ({} as any); - + compilation: ICompiler; +}): Plugin => { return { - postcssPlugin: 'libuild-postcss-url', + postcssPlugin: 'postcss-url', async Declaration(decl) { const isProcessed = (decl as any)[Processed]; @@ -32,12 +30,13 @@ export const postcssUrlPlugin = (options: { !isProcessed ) { let filePath = URL; - const { css_resolve, outdir, outbase, bundle } = - options.compilation.config; + const { outDir, sourceDir, buildType } = options.compilation.config; + const { css_resolve } = options.compilation; filePath = css_resolve(URL, dirname(options.entryPath)); - const rebaseFrom = bundle - ? outdir - : join(outdir, relative(outbase, dirname(options.entryPath))); + const rebaseFrom = + buildType === 'bundle' + ? outDir + : join(outDir, relative(sourceDir, dirname(options.entryPath))); const { contents: fileUrl } = await getAssetContents.apply( options.compilation, [filePath, rebaseFrom], @@ -49,5 +48,5 @@ export const postcssUrlPlugin = (options: { }, ); }, - } as Plugin; + }; }; diff --git a/packages/libuild/libuild-core/src/plugins/style/sassRender.ts b/packages/solutions/module-tools/src/builder/feature/style/sassRender.ts similarity index 78% rename from packages/libuild/libuild-core/src/plugins/style/sassRender.ts rename to packages/solutions/module-tools/src/builder/feature/style/sassRender.ts index a36c7d08d21a..6729ce642b15 100644 --- a/packages/libuild/libuild-core/src/plugins/style/sassRender.ts +++ b/packages/solutions/module-tools/src/builder/feature/style/sassRender.ts @@ -1,11 +1,11 @@ import { readFileSync } from 'fs'; import path from 'path'; -import { ILibuilder, Style } from '../../types'; +import { ICompiler, Style } from '../../../types'; import { loadProcessor, rebaseUrls } from './utils'; import { PreprocessRender } from './transformStyle'; export const sassRender: PreprocessRender = async function ( - this: ILibuilder, + this: ICompiler, content: string, _: string, stdinDir: string, @@ -13,7 +13,7 @@ export const sassRender: PreprocessRender = async function ( resolvePathMap: Map, implementation?: object | string, ) { - const sass = await loadProcessor('sass', this.config.root, implementation); + const sass = await loadProcessor('sass', this.context.root, implementation); return new Promise((resolve, reject) => { sass.render( { @@ -32,13 +32,13 @@ export const sassRender: PreprocessRender = async function ( const prependUnderScoreBaseUrl = `_${removeUnderScoreBaseUrl}`; try { const id = path.join(dirUrl, prependUnderScoreBaseUrl); - filePath = this.config.css_resolve( + filePath = this.css_resolve( id, dir === 'stdin' ? stdinDir : resolvePathMap.get(dir)!, ); } catch (err) { const id = path.join(dirUrl, removeUnderScoreBaseUrl); - filePath = this.config.css_resolve( + filePath = this.css_resolve( id, dir === 'stdin' ? stdinDir : resolvePathMap.get(dir)!, ); @@ -50,13 +50,11 @@ export const sassRender: PreprocessRender = async function ( path.dirname(filePath), ); } - rebaseUrls(filePath, stdinDir, this.config.css_resolve).then( - value => { - done({ - contents: value.contents || readFileSync(value.file, 'utf-8'), - }); - }, - ); + rebaseUrls(filePath, stdinDir, this.css_resolve).then(value => { + done({ + contents: value.contents || readFileSync(value.file, 'utf-8'), + }); + }); }, ], ...options, diff --git a/packages/libuild/libuild-core/src/plugins/style/transformStyle.ts b/packages/solutions/module-tools/src/builder/feature/style/transformStyle.ts similarity index 63% rename from packages/libuild/libuild-core/src/plugins/style/transformStyle.ts rename to packages/solutions/module-tools/src/builder/feature/style/transformStyle.ts index 20d325e23e43..84b7f002058e 100644 --- a/packages/libuild/libuild-core/src/plugins/style/transformStyle.ts +++ b/packages/solutions/module-tools/src/builder/feature/style/transformStyle.ts @@ -1,8 +1,6 @@ import path from 'path'; import { PartialMessage } from 'esbuild'; -import { resolvePathAndQuery } from '@modern-js/libuild-utils'; -import { ILibuilder, Source } from '../../types'; -import { LibuildError } from '../../error'; +import { ICompiler, Source } from '../../../types'; import { postcssTransformer } from './postcssTransformer'; import { lessRender } from './lessRender'; import { sassRender } from './sassRender'; @@ -11,7 +9,7 @@ const cssLangs = `\\.(css|less|sass|scss)($|\\?)`; const cssLangRE = new RegExp(cssLangs); const cssRender: PreprocessRender = async function ( - this: ILibuilder, + this: ICompiler, content: string, ) { return { @@ -24,6 +22,7 @@ export type PreprocessRender = ( stdinDir: string, preprocessOptions: any, resolvePathMap: Map, + implementation?: object | string, ) => Promise<{ css: Buffer | string; errors?: PartialMessage[]; @@ -31,42 +30,47 @@ export type PreprocessRender = ( map?: Buffer | string; }>; -const renderMap: Record = { +const renderMap: Record = { less: lessRender, sass: sassRender, scss: sassRender, css: cssRender, }; -export async function transformStyle(this: ILibuilder, source: Source) { +export async function transformStyle(this: ICompiler, source: Source) { const lang = source.path.match(cssLangRE)?.[1]; if (!lang) { - throw new LibuildError( - 'UNSUPPORTED_CSS_LANG', - `not supported css lang${lang}`, - ); + throw new Error(`UNSUPPORTED_CSS_LANG: not supported css lang${lang}`); } const { less, sass } = this.config.style; - const options = lang === 'less' ? less?.lessOptions : sass?.sassOptions; - const additionalData = - lang === 'less' ? less?.additionalData : sass?.additionalData; - const implementation = - lang === 'less' ? less?.implementation : sass?.implementation; + let options; + let additionalData; + let implementation; + if (lang === 'less') { + options = less?.lessOptions; + additionalData = less?.additionalData; + implementation = less?.implementation; + } + if (lang === 'scss' || lang === 'sass') { + options = sass?.sassOptions; + additionalData = sass?.additionalData; + implementation = sass?.implementation; + } + const preprocessRender = renderMap[lang]; - const { originalFilePath } = resolvePathAndQuery(source.path); - const stdinDir = path.dirname(originalFilePath); + const stdinDir = path.dirname(source.path); const resolvePathMap = new Map(); let content = ''; if (typeof additionalData === 'string') { content = `${additionalData}\n`; } else if (typeof additionalData === 'function') { - content = `${additionalData(originalFilePath)}\n`; + content = `${additionalData(source.path)}\n`; } content += source.code; const renderResult = await preprocessRender.apply(this, [ content, - originalFilePath, + source.path, stdinDir, options, resolvePathMap, @@ -75,7 +79,7 @@ export async function transformStyle(this: ILibuilder, source: Source) { const css = renderResult.css.toString(); const { code, loader } = await postcssTransformer( css ?? '', - originalFilePath, + source.path, this, ); return { diff --git a/packages/libuild/libuild-core/src/plugins/style/utils.ts b/packages/solutions/module-tools/src/builder/feature/style/utils.ts similarity index 89% rename from packages/libuild/libuild-core/src/plugins/style/utils.ts rename to packages/solutions/module-tools/src/builder/feature/style/utils.ts index f2629e17419a..ff3e7fcac95b 100644 --- a/packages/libuild/libuild-core/src/plugins/style/utils.ts +++ b/packages/solutions/module-tools/src/builder/feature/style/utils.ts @@ -1,14 +1,6 @@ import fs from 'fs'; import path from 'path'; -import { createHash } from 'crypto'; - -export function getHash( - content: Buffer | string, - encoding: any, - type = 'md5', -): string { - return createHash(type).update(content.toString(), encoding).digest('hex'); -} +import { normalizeSlashes } from '../../../utils'; const cache: Record = {}; /** @@ -59,11 +51,11 @@ type CssUrlReplacer = ( * root file as base. */ export async function rebaseUrls( - file: string, + filepath: string, rootDir: string, resolver: (id: string, dir: string) => string, ): Promise<{ file: string; contents?: string }> { - file = path.resolve(file); // ensure os-specific flashes + const file = path.resolve(filepath); // ensure os-specific flashes // in the same dir, no need to rebase const fileDir = path.dirname(file); if (fileDir === rootDir) { @@ -115,7 +107,7 @@ export function rewriteCssUrls( return matched; } - return `url(${wrap}${await replacer(rawUrl)}${wrap})`; + return `url(${wrap}${normalizeSlashes(await replacer(rawUrl))}${wrap})`; }); } @@ -127,6 +119,7 @@ async function asyncReplace( let match: RegExpExecArray | null; let remaining = input; let rewritten = ''; + // eslint-disable-next-line no-cond-assign while ((match = re.exec(remaining))) { rewritten += remaining.slice(0, match.index); rewritten += await replacer(match); diff --git a/packages/solutions/module-tools/src/builder/feature/swc.ts b/packages/solutions/module-tools/src/builder/feature/swc.ts new file mode 100644 index 000000000000..46299dad3c45 --- /dev/null +++ b/packages/solutions/module-tools/src/builder/feature/swc.ts @@ -0,0 +1,186 @@ +import type { TransformConfig, JscTarget } from '@modern-js/swc-plugins'; +import { Compiler } from '@modern-js/swc-plugins'; +import type { ICompiler, Source, TsTarget, ITsconfig } from '../../types'; +import { + isJsExt, + isJsLoader, + isTsExt, + isTsLoader, + tsTargetAtOrAboveES2022, +} from '../../utils'; + +const name = 'swc:transform'; +const getSwcTarget = (target: string): JscTarget => { + // refer to JscTarget + const list = [ + 'es3', + 'es5', + 'es2015', + 'es2016', + 'es2017', + 'es2018', + 'es2019', + 'es2020', + 'es2021', + 'es2022', + ]; + if (list.includes(target)) { + return target as JscTarget; + } + + if (target === 'next') { + return 'es2022'; + } + + if (target === 'es6') { + return 'es2015'; + } + + return 'es2022'; +}; + +export const swcTransform = (userTsconfig: ITsconfig) => ({ + name, + apply(compiler: ICompiler) { + const tsUseDefineForClassFields = + userTsconfig?.compilerOptions?.useDefineForClassFields; + const emitDecoratorMetadata = + userTsconfig?.compilerOptions?.emitDecoratorMetadata ?? false; + + // https://www.typescriptlang.org/tsconfig#useDefineForClassFields + let useDefineForClassFields: boolean; + let tsTarget = userTsconfig?.compilerOptions?.target; + + tsTarget = tsTarget ? (tsTarget.toLowerCase() as TsTarget) : undefined; + if (tsUseDefineForClassFields !== undefined) { + useDefineForClassFields = tsUseDefineForClassFields; + } else if (tsTarget !== undefined) { + useDefineForClassFields = tsTargetAtOrAboveES2022(tsTarget); + } else { + useDefineForClassFields = true; + } + + const { transformImport, transformLodash, externalHelpers } = + compiler.config; + + compiler.hooks.transform.tapPromise( + { name }, + async (source): Promise => { + const { path } = source; + // Todo: emitDecoratorMetadata default value + const isTs = isTsLoader(source.loader) || isTsExt(path); + const enableJsx = + source.loader === 'tsx' || + source.loader === 'jsx' || + /\.tsx$|\.jsx$/i.test(path); + + if (isJsExt(path) || isJsLoader(source.loader)) { + const { target, jsx } = compiler.config; + + const swcCompilerOptions: TransformConfig = { + filename: path, + sourceMaps: Boolean(compiler.config.sourceMap), + inputSourceMap: false, + swcrc: false, + configFile: false, + jsc: { + parser: isTs + ? { + syntax: 'typescript', + tsx: enableJsx, + decorators: true, + } + : { + syntax: 'ecmascript', + jsx: enableJsx, + decorators: true, + }, + transform: { + react: { + runtime: jsx === 'transform' ? 'classic' : 'automatic', + }, + useDefineForClassFields, + legacyDecorator: emitDecoratorMetadata ? true : undefined, + decoratorMetadata: emitDecoratorMetadata ? true : undefined, + }, + externalHelpers, + target: getSwcTarget(target), + }, + isModule: 'unknown', + extensions: { + pluginImport: transformImport, + lodash: transformLodash + ? { + cwd: compiler.context.root, + ids: ['lodash', 'lodash-es'], + } + : undefined, + }, + }; + + const swcCompiler = new Compiler(swcCompilerOptions); + const result = await swcCompiler.transform(path, source.code); + return { + ...source, + code: result.code, + map: + typeof result.map === 'string' + ? JSON.parse(result.map) + : result.map, + }; + } + return source; + }, + ); + }, +}); + +export const swcRenderChunk = { + name: 'swc:renderChunk', + apply(compiler: ICompiler) { + compiler.hooks.renderChunk.tapPromise( + { name: 'swc:renderChunk' }, + async chunk => { + if (chunk.fileName.endsWith('.js') && chunk.type === 'chunk') { + const { umdModuleName, format } = compiler.config; + const name = + typeof umdModuleName === 'function' + ? umdModuleName(chunk.fileName) + : umdModuleName; + const swcCompiler = new Compiler({ + filename: name, + sourceMaps: Boolean(compiler.config.sourceMap), + inputSourceMap: false, + swcrc: false, + configFile: false, + extensions: {}, + jsc: { + target: getSwcTarget(compiler.config.target), + parser: { syntax: 'ecmascript' }, + }, + module: + format === 'umd' + ? { + type: 'umd', + } + : undefined, + isModule: 'unknown', + }); + const result = await swcCompiler.transform( + name, + chunk.contents.toString(), + ); + return { + ...chunk, + contents: result.code, + map: + typeof result.map === 'string' + ? JSON.parse(result.map) + : result.map, + }; + } + return chunk; + }, + ); + }, +}; diff --git a/packages/solutions/module-tools/src/builder/feature/terser.ts b/packages/solutions/module-tools/src/builder/feature/terser.ts new file mode 100644 index 000000000000..ed80495bf67f --- /dev/null +++ b/packages/solutions/module-tools/src/builder/feature/terser.ts @@ -0,0 +1,67 @@ +import { isObject, lodash } from '@modern-js/utils'; +import { + minify as terserMinify, + MinifyOptions as TerserMinifyOptions, +} from 'terser'; +import { ChunkType, ICompiler } from '../../types'; +import { normalizeSourceMap } from '../../utils'; + +const name = 'terser'; +const apply = (compiler: ICompiler) => { + compiler.hooks.renderChunk.tapPromise({ name }, async chunk => { + const { sourceMap, minify } = compiler.config; + if (chunk.type === ChunkType.chunk) { + const code = chunk.contents.toString(); + const needSourceMap = Boolean(sourceMap); + const terserOptions = resolveTerserOptions( + minify as TerserMinifyOptions | 'terser', + { + sourceMap: Boolean(needSourceMap), + }, + ); + const result = await terserMinify(code, { + ...terserOptions, + sourceMap: needSourceMap, + }); + return { + ...chunk, + contents: result.code || chunk.contents, + map: normalizeSourceMap(result.map as any, { needSourceMap }), + }; + } + return chunk; + }); +}; + +export const minify = { + name, + apply, +}; + +function resolveTerserOptions( + terserOptions: TerserMinifyOptions | 'terser', + { sourceMap }: { sourceMap: boolean }, +): TerserMinifyOptions { + // cra: https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L237 + return lodash.merge( + { + compress: { + inline: 2, + comparisons: false, + }, + format: { keep_quoted_props: true, comments: false }, + // Return object to avoid redundant `JSON.parse` in remapping + sourceMap: sourceMap + ? { + asObject: true, + // `includeSources` is not necessary for minification, + // and we can utilize this to reduce the size of the source map. + includeSources: false, + } + : false, + safari10: true, + toplevel: true, + }, + isObject(terserOptions) ? terserOptions : {}, + ); +} diff --git a/packages/solutions/module-tools/src/builder/index.ts b/packages/solutions/module-tools/src/builder/index.ts index 122c599a8d7c..123c225fce47 100644 --- a/packages/solutions/module-tools/src/builder/index.ts +++ b/packages/solutions/module-tools/src/builder/index.ts @@ -8,6 +8,7 @@ import type { ModuleTools, } from '../types'; import pMap from '../../compiled/p-map'; +import { debug } from '../debug'; import { runBuildTask } from './build'; import { clearBuildConfigPaths, clearDtsTemp } from './clear'; @@ -28,10 +29,11 @@ export const run = async ( if (resolvedBuildConfig.length !== 0) { totalDuration = Date.now(); - await clearBuildConfigPaths(resolvedBuildConfig, { - noClear: !clear, - projectAbsRootPath: context.appDirectory, - }); + if (clear) { + debug('clear output paths'); + await clearBuildConfigPaths(resolvedBuildConfig, context.appDirectory); + debug('clear output paths done'); + } await clearDtsTemp(); if (watch) { @@ -42,8 +44,9 @@ export const run = async ( await pMap( resolvedBuildConfig, async config => { + debug('run beforeBuildTask hooks'); const buildConfig = await runner.beforeBuildTask(config); - + debug('run beforeBuildTask hooks done'); await runBuildTask( { buildConfig, @@ -52,7 +55,9 @@ export const run = async ( }, api, ); + debug('run afterBuildTask hooks'); await runner.afterBuildTask({ status: 'success', config }); + debug('run afterBuildTask hooks done'); }, { concurrency: os.cpus().length }, ); @@ -77,6 +82,7 @@ export const run = async ( ), ); } + debug('run afterBuild hooks'); await runner.afterBuild({ status: 'success', @@ -84,4 +90,5 @@ export const run = async ( commandOptions: cmdOptions, totalDuration, }); + debug('run afterBuild hooks done'); }; diff --git a/packages/solutions/module-tools/src/cli.ts b/packages/solutions/module-tools/src/cli.ts index 78c820fc5635..98c42d2b69b0 100644 --- a/packages/solutions/module-tools/src/cli.ts +++ b/packages/solutions/module-tools/src/cli.ts @@ -9,9 +9,8 @@ import { newCommand, upgradeCommand, } from './command'; -import { initLocalLanguage } from './utils/language'; -import { addExitListener } from './utils/onExit'; import { isLegacyUserConfig } from './config/merge'; +import { addExitListener } from './utils/onExit'; import { legacySchema } from './config/legacySchema'; import { schema } from './config/schema'; @@ -30,7 +29,12 @@ const setup: CliPlugin['setup'] = async api => { }); const prepare = async () => { - await initLocalLanguage(); + const local = await import('./locale'); + const { getLocaleLanguage } = await import( + '@modern-js/plugin-i18n/language-detector' + ); + const locale = getLocaleLanguage(); + local.i18n.changeLanguage({ locale }); const appContext = api.useAppContext(); dotenv.config(); diff --git a/packages/solutions/module-tools/src/command.ts b/packages/solutions/module-tools/src/command.ts index 590e51e71907..d9419e8836c1 100644 --- a/packages/solutions/module-tools/src/command.ts +++ b/packages/solutions/module-tools/src/command.ts @@ -3,7 +3,13 @@ import type { PluginAPI } from '@modern-js/core'; import type { ModuleTools } from './types'; import type { DevCommandOptions, BuildCommandOptions } from './types/command'; import { i18n, localeKeys } from './locale'; -import { initModuleContext } from './utils/context'; + +const initModuleContext = async (api: PluginAPI) => { + const { isTypescript } = await import('@modern-js/utils'); + const { appDirectory, srcDirectory } = api.useAppContext(); + const isTsProject = isTypescript(appDirectory); + return { isTsProject, appDirectory, srcDirectory }; +}; export const buildCommand = async ( program: Command, @@ -13,7 +19,7 @@ export const buildCommand = async ( .command('build') .usage('[options]') .description(i18n.t(localeKeys.command.build.describe)) - .option('-w, --watch', i18n.t(localeKeys.command.build.watch)) + .option('-w, --watch', i18n.t(localeKeys.command.build.watch), false) .option('--tsconfig [tsconfig]', i18n.t(localeKeys.command.build.tsconfig)) .option( '-p, --platform [platform...]', @@ -57,21 +63,8 @@ export const devCommand = async ( for (const subCmd of meta.subCommands) { devProgram.command(subCmd).action(async (options: DevCommandOptions) => { const context = await initModuleContext(api); - - // TODO: watch build - // const { ensureFirstBuild, watchBuild } = await import('./dev'); - // await ensureFirstBuild(api, context, options, { - // disableRunBuild: meta.disableRunBuild ?? false, - // appDirectory: context.appDirectory, - // }); - await runner.beforeDevTask(meta); await meta.action(options, { isTsProject: context.isTsProject }); - // TODO: watch build - // await watchBuild(api, context, options, { - // disableRunBuild: meta.disableRunBuild ?? false, - // appDirectory: context.appDirectory, - // }); }); } } diff --git a/packages/solutions/module-tools/src/config/merge.ts b/packages/solutions/module-tools/src/config/merge.ts index d938b4dfb785..61405b5c1cec 100644 --- a/packages/solutions/module-tools/src/config/merge.ts +++ b/packages/solutions/module-tools/src/config/merge.ts @@ -7,8 +7,7 @@ import type { ModuleLegacyUserConfig, BuildCommandOptions, } from '../types'; -import { getAllDeps } from '../utils/builder'; -import { normalizeInput } from '../utils/input'; +import { normalizeInput, getAllDeps } from '../utils'; import { getDefaultBuildConfig } from '../constants/build'; export const mergeDefaultBaseConfig = async ( @@ -20,8 +19,7 @@ export const mergeDefaultBaseConfig = async ( const { applyOptionsChain, ensureAbsolutePath, slash } = await import( '@modern-js/utils' ); - const { getDefaultIndexEntry } = await import('../utils/input'); - const { getStyleConfig } = await import('../utils/style'); + const { getDefaultIndexEntry, getStyleConfig } = await import('../utils'); const defaultAlias = { '@': context.srcDirectory, }; @@ -83,11 +81,8 @@ export const mergeDefaultBaseConfig = async ( ...pConfig.dts, } as DTSOptions); - if (dts) { - if (cmdTsconfigPath) { - dts.tsconfigPath = cmdTsconfigPath; - } - } + const tsconfig = + cmdTsconfigPath ?? pConfig.tsconfig ?? defaultConfig.tsconfig; let externals = pConfig.externals ?? defaultConfig.externals; const autoExternal = pConfig.autoExternal ?? defaultConfig.autoExternal; @@ -107,9 +102,22 @@ export const mergeDefaultBaseConfig = async ( ...(externals || []), ]; } + const platform = pConfig.platform ?? defaultConfig.platform; + const defaultMainFields = + platform === 'node' ? ['module', 'main'] : ['module', 'browser', 'main']; + const resolve = { + mainFields: pConfig.resolve?.mainFields ?? defaultMainFields, + jsExtensions: + pConfig.resolve?.jsExtensions ?? defaultConfig.resolve.jsExtensions, + }; const esbuildOptions = pConfig.esbuildOptions ?? defaultConfig.esbuildOptions; return { + footer: pConfig.footer ?? defaultConfig.footer, + banner: pConfig.banner ?? defaultConfig.banner, + resolve, + tsconfig, + hooks: pConfig.hooks ?? defaultConfig.hooks, asset, buildType, format: pConfig.format ?? defaultConfig.format, @@ -120,7 +128,7 @@ export const mergeDefaultBaseConfig = async ( dts, jsx: pConfig.jsx ?? defaultConfig.jsx, input, - platform: pConfig.platform ?? defaultConfig.platform, + platform, splitting: pConfig.splitting ?? defaultConfig.splitting, minify: pConfig.minify ?? defaultConfig.minify, autoExternal, @@ -150,6 +158,7 @@ export const mergeDefaultBaseConfig = async ( }, esbuildOptions, externalHelpers: pConfig.externalHelpers ?? defaultConfig.externalHelpers, + transformCache: pConfig.transformCache ?? defaultConfig.transformCache, transformImport: pConfig.transformImport ?? defaultConfig.transformImport, transformLodash: pConfig.transformLodash ?? defaultConfig.transformLodash, sourceType: pConfig.sourceType ?? defaultConfig.sourceType, diff --git a/packages/solutions/module-tools/src/config/normalize.ts b/packages/solutions/module-tools/src/config/normalize.ts index 8b2b0be13ce1..62bb43eae645 100644 --- a/packages/solutions/module-tools/src/config/normalize.ts +++ b/packages/solutions/module-tools/src/config/normalize.ts @@ -1,7 +1,7 @@ import path from 'path'; import type { PluginAPI } from '@modern-js/core'; import _ from '@modern-js/utils/lodash'; -import { ensureArray, slash } from '@modern-js/utils'; +import { ensureArray } from '@modern-js/utils'; import type { ModuleUserConfig, ModuleLegacyUserConfig, @@ -86,7 +86,7 @@ export const normalizeBuildConfig = async ( const mergedConfig = mergeConfig(configFromPreset, buildConfig ?? {}); - validPartialBuildConfig(mergedConfig); + validPartialBuildConfig(mergedConfig, context.appDirectory); const normalizedConfig = await Promise.all( mergedConfig.map(async config => { @@ -114,20 +114,25 @@ export const transformToAbsPath = async ( newConfig.outDir = path.resolve(context.appDirectory, newConfig.outDir); - newConfig.sourceDir = slash( - path.resolve(context.appDirectory, baseConfig.sourceDir), + newConfig.sourceDir = path.resolve( + context.appDirectory, + baseConfig.sourceDir, ); + newConfig.tsconfig = path.resolve(context.appDirectory, newConfig.tsconfig); + // dts path if (newConfig.dts) { newConfig.dts.distPath = path.resolve( newConfig.outDir, newConfig.dts.distPath, ); - newConfig.dts.tsconfigPath = path.resolve( - context.appDirectory, - newConfig.dts.tsconfigPath, - ); + if (newConfig.dts.tsconfigPath) { + newConfig.dts.tsconfigPath = path.resolve( + context.appDirectory, + newConfig.dts.tsconfigPath, + ); + } } return newConfig; diff --git a/packages/solutions/module-tools/src/config/schema.ts b/packages/solutions/module-tools/src/config/schema.ts index a0ca312de326..fe230c1432d8 100644 --- a/packages/solutions/module-tools/src/config/schema.ts +++ b/packages/solutions/module-tools/src/config/schema.ts @@ -33,6 +33,18 @@ const buildConfigProperties = { alias: { typeof: ['object', 'function'], }, + hooks: { + // TODO: improve it + type: 'array', + }, + resolve: { + // TODO: add properties + type: 'object', + }, + banner: { + // TODO: add properties + type: 'object', + }, asset: { type: 'object', }, @@ -113,7 +125,7 @@ const buildConfigProperties = { type: ['array', 'object'], }, jsx: { - enum: ['automatic', 'transform'], + enum: ['automatic', 'transform', 'preserve'], }, minify: { if: { @@ -179,6 +191,9 @@ const buildConfigProperties = { externalHelpers: { type: 'boolean', }, + tsconfig: { + type: 'string', + }, transformImport: { type: 'array', }, diff --git a/packages/solutions/module-tools/src/config/transformLegacyConfig.ts b/packages/solutions/module-tools/src/config/transformLegacyConfig.ts index 356f2f4b5ef3..d8e8d86e69f5 100644 --- a/packages/solutions/module-tools/src/config/transformLegacyConfig.ts +++ b/packages/solutions/module-tools/src/config/transformLegacyConfig.ts @@ -177,10 +177,7 @@ export const createConfigByBuildConfig = async ( }; } if (config.tsconfig) { - newConfig.dts = { - ...(typeof newConfig.dts === 'object' ? newConfig.dts : {}), - tsconfigPath: config.tsconfig, - }; + newConfig.tsconfig = config.tsconfig; } // check enableDts must be last if (!config.enableDts) { diff --git a/packages/solutions/module-tools/src/config/valid.ts b/packages/solutions/module-tools/src/config/valid.ts index ff9f7f19af39..0b2bba7fb8d5 100644 --- a/packages/solutions/module-tools/src/config/valid.ts +++ b/packages/solutions/module-tools/src/config/valid.ts @@ -1,16 +1,25 @@ +import path from 'path'; +import { fs } from '@modern-js/utils'; import type { PartialBuildConfig, PartialBaseBuildConfig } from '../types'; -export const validPartialBuildConfig = (config: PartialBuildConfig) => { +export const validPartialBuildConfig = ( + config: PartialBuildConfig, + appDirectory: string, +) => { if (Array.isArray(config)) { for (const c of config) { - validBuildTypeAndFormat(c); + validBuildConfig(c, appDirectory); } } else { - validBuildTypeAndFormat(config); + validBuildConfig(config, appDirectory); } }; -export const validBuildTypeAndFormat = (config: PartialBaseBuildConfig) => { +export const validBuildConfig = ( + config: PartialBaseBuildConfig, + appDirectory: string, +) => { + // valid format if ( config.buildType === 'bundleless' && ['iife', 'umd'].includes(config.format ?? '') @@ -19,4 +28,12 @@ export const validBuildTypeAndFormat = (config: PartialBaseBuildConfig) => { `when buildType is bundleless, the format must be equal to one of the allowed values: (cjs, esm)`, ); } + + // valid tsconfigPath + if ( + config.tsconfig && + !fs.existsSync(path.resolve(appDirectory, config.tsconfig)) + ) { + throw new Error(`${config.tsconfig} does not exist in your project`); + } }; diff --git a/packages/solutions/module-tools/src/constants/build.ts b/packages/solutions/module-tools/src/constants/build.ts index 44c55c2547e0..255b728c6784 100644 --- a/packages/solutions/module-tools/src/constants/build.ts +++ b/packages/solutions/module-tools/src/constants/build.ts @@ -2,58 +2,72 @@ import type { BaseBuildConfig } from '../types'; export const getDefaultBuildConfig = () => { return Object.freeze({ + alias: {}, + asset: { + limit: 14336, + path: 'assets', + publicPath: '', + svgr: false, + }, + autoExternal: true, + banner: {}, buildType: 'bundle', - format: 'cjs', - target: 'es6', - sourceMap: false, copy: {}, - outDir: './dist', + define: {}, + disableSwcTransform: false, dts: Object.freeze({ only: false, distPath: './', - tsconfigPath: './tsconfig.json', + tsconfigPath: undefined, abortOnError: true, respectExternal: true, }), - jsx: 'automatic', - input: ['src/index.ts'], - platform: 'node', - splitting: false, + esbuildOptions: c => c, + externalHelpers: false, externals: [], - minify: false, - autoExternal: true, - umdGlobals: {}, - sourceDir: './src', - alias: {}, + format: 'cjs', + footer: {}, + hooks: [], + input: ['src/index.ts'], + jsx: 'automatic', metafile: false, - umdModuleName: name => name, - define: {}, - asset: { - path: 'assets', - limit: 14336, - publicPath: '', - svgr: false, + minify: false, + outDir: './dist', + platform: 'node', + redirect: { + alias: true, + asset: true, + style: true, }, + resolve: { + mainFields: ['module', 'main'], + jsExtensions: ['.jsx', '.tsx', '.js', '.ts', '.json'], + }, + sideEffects: undefined, + sourceDir: './src', + sourceMap: false, + sourceType: 'module', + splitting: false, style: { + autoModules: true, + inject: false, less: {}, - sass: {}, + modules: {}, postcss: {}, + sass: {}, tailwindcss: {}, - inject: false, - autoModules: true, - modules: {}, - }, - sideEffects: undefined, - redirect: { - alias: true, - style: true, - asset: true, }, - esbuildOptions: c => c, - externalHelpers: false, + target: 'es6', + transformCache: true, transformImport: [], - transformLodash: true, - sourceType: 'module', - disableSwcTransform: false, + transformLodash: false, + tsconfig: 'tsconfig.json', + umdGlobals: {}, + umdModuleName: name => name, }); }; + +/** + * supports require js plugin in less file + */ +export const cssExtensions = ['.less', '.css', '.sass', '.scss', '.js']; diff --git a/packages/solutions/module-tools/src/constants/file.ts b/packages/solutions/module-tools/src/constants/file.ts index 5ca1b791e927..90cf29da6900 100644 --- a/packages/solutions/module-tools/src/constants/file.ts +++ b/packages/solutions/module-tools/src/constants/file.ts @@ -1,3 +1,23 @@ -export const assetExts = ['.png', '.jpg', '.svg']; export const styleExts = ['.css', '.less', '.sass', '.scss']; export const dtsAliasExts = ['.d.ts']; +export const assetExt = [ + '.svg', + '.png', + '.jpg', + '.jpeg', + '.gif', + '.webp', + '.ttf', + '.otf', + '.woff', + '.woff2', + '.eot', + '.mp3', + '.mp4', + '.webm', + '.ogg', + '.wav', + '.flac', + '.aac', + '.mov', +]; diff --git a/packages/libuild/libuild-core/src/constants/loader.ts b/packages/solutions/module-tools/src/constants/loader.ts similarity index 92% rename from packages/libuild/libuild-core/src/constants/loader.ts rename to packages/solutions/module-tools/src/constants/loader.ts index adddf92682ae..b1dee40ec04a 100644 --- a/packages/libuild/libuild-core/src/constants/loader.ts +++ b/packages/solutions/module-tools/src/constants/loader.ts @@ -1,4 +1,4 @@ -import { Loader } from 'esbuild'; +import type { Loader } from 'esbuild'; export const loaderMap: Record = { '.aac': 'file', diff --git a/packages/solutions/module-tools/src/debug.ts b/packages/solutions/module-tools/src/debug.ts new file mode 100644 index 000000000000..abc06b7d9752 --- /dev/null +++ b/packages/solutions/module-tools/src/debug.ts @@ -0,0 +1,9 @@ +import { debug as Debugger, chalk } from '@modern-js/utils'; + +export const debug = Debugger('module'); + +export const label = (info: string) => { + return chalk.blue(`[${info.toUpperCase()}]`); +}; + +export const debugResolve = Debugger('module:resolve'); diff --git a/packages/solutions/module-tools/src/error.ts b/packages/solutions/module-tools/src/error.ts index bd160ed9eedc..23a5491e63f5 100644 --- a/packages/solutions/module-tools/src/error.ts +++ b/packages/solutions/module-tools/src/error.ts @@ -91,8 +91,12 @@ export class InternalBuildError extends Error { endLine, chalk.blue.bold.underline(`\nDetailed Information: `), ); - msgs.push(e.toString()); - msgs.push(e.stack || ''); + + if (e.stack) { + msgs.push(e.stack); + } else { + msgs.push(e.message); + } return msgs; } diff --git a/packages/solutions/module-tools/src/hooks/build.ts b/packages/solutions/module-tools/src/hooks/build.ts index 3ff0d20b71bf..cc8a454c476d 100644 --- a/packages/solutions/module-tools/src/hooks/build.ts +++ b/packages/solutions/module-tools/src/hooks/build.ts @@ -4,14 +4,15 @@ import { } from '@modern-js/plugin'; import type { RegisterBuildPlatformResult } from '@modern-js/core'; import { BuildCommandOptions } from '../types'; -import type { BuildConfig, BaseBuildConfig } from '../types/config'; import type { BuildTaskResult, BuildResult, BuildPlatformResult, WatchDtsHookContext, WatchJsHookContext, -} from '../types/hooks'; + BuildConfig, + BaseBuildConfig, +} from '../types'; export const buildHooks = { beforeBuild: createParallelWorkflow< diff --git a/packages/solutions/module-tools/src/hooks/misc.ts b/packages/solutions/module-tools/src/hooks/misc.ts index 5ed372c1a160..4f7940289232 100644 --- a/packages/solutions/module-tools/src/hooks/misc.ts +++ b/packages/solutions/module-tools/src/hooks/misc.ts @@ -1,7 +1,10 @@ -import { createAsyncPipeline, createAsyncWaterfall } from '@modern-js/plugin'; -import type { CLIConfig } from '@modern-js/libuild'; +import { createAsyncWaterfall, createAsyncPipeline } from '@modern-js/plugin'; export const miscHooks = { addRuntimeExports: createAsyncWaterfall(), - modifyLibuild: createAsyncPipeline(), + /** + * @deprecated + * use buildConfig.hooks and buildConfig.esbuildOptions instead. + */ + modifyLibuild: createAsyncPipeline(), }; diff --git a/packages/solutions/module-tools/src/index.ts b/packages/solutions/module-tools/src/index.ts index 985324f9e939..0d627b6edae9 100644 --- a/packages/solutions/module-tools/src/index.ts +++ b/packages/solutions/module-tools/src/index.ts @@ -5,3 +5,5 @@ export { legacyPresets } from './constants/legacy-preset'; export * from './types'; export { moduleTools }; export default moduleTools; + +export * from './utils/assert'; diff --git a/packages/solutions/module-tools/src/locale/index.ts b/packages/solutions/module-tools/src/locale/index.ts index 72b7042d21d2..e28642c3ee6c 100644 --- a/packages/solutions/module-tools/src/locale/index.ts +++ b/packages/solutions/module-tools/src/locale/index.ts @@ -1,14 +1,8 @@ -import { Import } from '@modern-js/utils'; - +import { I18n } from '@modern-js/plugin-i18n'; import { ZH_LOCALE } from './zh'; import { EN_LOCALE } from './en'; -const i18nPlugin: typeof import('@modern-js/plugin-i18n') = Import.lazy( - '@modern-js/plugin-i18n', - require, -); - -const i18n = new i18nPlugin.I18n(); +const i18n = new I18n(); const localeKeys = i18n.init('en', { zh: ZH_LOCALE, en: EN_LOCALE }); diff --git a/packages/solutions/module-tools/src/types/command.ts b/packages/solutions/module-tools/src/types/command.ts index 80555bd5f352..46d249ec0dd7 100644 --- a/packages/solutions/module-tools/src/types/command.ts +++ b/packages/solutions/module-tools/src/types/command.ts @@ -4,10 +4,10 @@ export interface DevCommandOptions { } export interface BuildCommandOptions { + clear: boolean; + dts: boolean; + watch: boolean; config?: string; - clear?: boolean; - dts?: boolean; platform?: boolean | string[]; tsconfig?: string; - watch?: boolean; } diff --git a/packages/solutions/module-tools/src/types/config/index.ts b/packages/solutions/module-tools/src/types/config/index.ts index f2d1779f4056..12d967775104 100644 --- a/packages/solutions/module-tools/src/types/config/index.ts +++ b/packages/solutions/module-tools/src/types/config/index.ts @@ -1,26 +1,29 @@ -import type { - UserConfig as LibuildUserConfig, - Asset as LibuildAsset, - Style as LibuildStyle, -} from '@modern-js/libuild'; -import type { Options } from '@modern-js/libuild-plugin-svgr'; -import type { ImportItem } from '@modern-js/libuild-plugin-swc'; -import type { ToolsConfig as WebpackBuilderToolsConfig } from '@modern-js/builder-webpack-provider'; +import type { BuildOptions } from 'esbuild'; +import type { ImportItem } from '@modern-js/swc-plugins'; +import type { Config } from '@svgr/core'; +import type { CreateFilter } from '@rollup/pluginutils'; +import type { MinifyOptions as TerserMinifyOptions } from 'terser'; import type { TestConfig } from '@modern-js/types'; import { internalPreset, presetList } from '../../constants/preset'; +import { ICompiler } from '../esbuild'; import type { CopyConfig } from './copy'; -import type { - LessConfig, - SassConfig, - PostCSSConfig, - TailwindCSSConfig, -} from './style'; +import type { Dev } from './dev'; +import type { Style, StyleConfig } from './style'; export * from './style'; -export type BuildType = 'bundleless' | 'bundle'; +export * from './dev'; -export type Format = 'esm' | 'cjs' | 'umd' | 'iife'; +export * from './copy'; + +export type HookList = { + name: string; + apply: (compiler: ICompiler) => void; +}[]; + +export type EsbuildOptions = (options: BuildOptions) => BuildOptions; + +export type BuildType = 'bundleless' | 'bundle'; export type Target = | 'es5' @@ -36,13 +39,47 @@ export type Target = // The default target is esnext which means that by default, assume all of the latest JavaScript and CSS features are supported. | 'esnext'; -export type Input = Required['input']; +export type Minify = 'esbuild' | 'terser' | false | TerserMinifyOptions; + +export type Format = 'esm' | 'cjs' | 'umd' | 'iife'; + +export type Input = + | { + [name: string]: string; + } + | string[]; + +export type Globals = Record; + +export type Define = Record; + +export type Externals = (string | RegExp)[]; + +export type Platform = 'node' | 'browser'; + +export type SideEffects = + | RegExp[] + | boolean + | ((id: string, external: boolean) => boolean); + +/** + * @experimental + */ +export type Redirect = { + alias?: boolean; + style?: boolean; + asset?: boolean; +}; export type DTSOptions = { abortOnError: boolean; distPath: string; - tsconfigPath: string; only: boolean; + /** + * @deprecated + * use buildConfig.tsconfig instead. + */ + tsconfigPath?: string; /** * Only for rollup-plugin-dts, see more in https://github.com/Swatinem/rollup-plugin-dts#what-to-expect. * We hope you use external to prevent them(like @types) which come from node_modules from be bundled. @@ -53,75 +90,108 @@ export type DTSOptions = { */ respectExternal: boolean; }; + export type DTS = false | Partial; +export interface SvgrOptions extends Config { + include?: Parameters[0]; + exclude?: Parameters[1]; +} + export interface Asset { - path?: LibuildAsset['outdir']; - limit?: LibuildAsset['limit']; - publicPath?: LibuildAsset['publicPath']; - svgr?: boolean | Options; + path?: string; + limit?: number; + publicPath?: string | ((filePath: string) => string); + svgr?: boolean | SvgrOptions; } -export type SourceMap = Required['sourceMap']; + export type AutoExternal = | boolean | { dependencies?: boolean; peerDependencies?: boolean; }; -export type JSX = 'automatic' | 'transform'; + +export type JSX = 'automatic' | 'transform' | 'preserve'; + export type ExternalHelpers = boolean; +export type BannerAndFooter = { + js?: string; + css?: string; + dts?: string; +}; + export type AliasOption = | Record | ((aliases: Record) => Record | void); +export type Resolve = { + mainFields?: string[]; + jsExtensions?: string[]; +}; + export type BaseBuildConfig = Omit< Required, - 'dts' | 'style' | 'alias' | 'sideEffects' + 'dts' | 'style' | 'alias' | 'sideEffects' | 'asset' | 'resolve' > & { - sideEffects: LibuildUserConfig['sideEffects']; + sideEffects?: SideEffects; dts: false | DTSOptions; - style: Omit, 'cleanCss'> & { - tailwindcss: TailwindCSSConfig; - }; + style: Style; alias: Record; + asset: Required; + resolve: Required; }; export type PartialBaseBuildConfig = { - sourceType?: 'commonjs' | 'module'; + resolve?: Resolve; + footer?: BannerAndFooter; + banner?: BannerAndFooter; buildType?: 'bundleless' | 'bundle'; format?: Format; target?: Target; dts?: DTS; - sourceMap?: SourceMap; + sourceMap?: boolean | 'inline' | 'external'; sourceDir?: string; copy?: CopyConfig; asset?: Asset; jsx?: JSX; outDir?: string; alias?: AliasOption; + hooks?: HookList; input?: Input; + tsconfig?: string; metafile?: boolean; - platform?: LibuildUserConfig['platform']; - splitting?: LibuildUserConfig['splitting']; - minify?: LibuildUserConfig['minify']; - externals?: LibuildUserConfig['external']; + platform?: Platform; + splitting?: boolean; + minify?: Minify; + externals?: Externals; autoExternal?: AutoExternal; - umdGlobals?: LibuildUserConfig['globals']; + umdGlobals?: Globals; umdModuleName?: ((chunkName: string) => string) | string | undefined; - define?: LibuildUserConfig['define']; + define?: Define; style?: StyleConfig; - redirect?: LibuildUserConfig['redirect']; - sideEffects?: LibuildUserConfig['sideEffects']; - esbuildOptions?: LibuildUserConfig['esbuildOptions']; - // Related to swc-transform + redirect?: Redirect; + sideEffects?: SideEffects; + esbuildOptions?: EsbuildOptions; + /** + * @internal + * cache transform result or not + */ + transformCache?: boolean; + // The following is related to swc-transform externalHelpers?: ExternalHelpers; transformImport?: ImportItem[]; transformLodash?: boolean; /** - * internal configuration + * @deprecated + * @internal */ disableSwcTransform?: boolean; + /** + * @deprecated + */ + sourceType?: 'commonjs' | 'module'; }; export type BuildConfig = BaseBuildConfig | BaseBuildConfig[]; @@ -139,29 +209,6 @@ export type BuildPreset = ) => PartialBaseBuildConfig[]; }) => PartialBaseBuildConfig[] | Promise); -export interface StyleConfig { - less?: LessConfig; - sass?: SassConfig; - postcss?: PostCSSConfig; - autoModules?: LibuildStyle['autoModules']; - modules?: LibuildStyle['modules']; - inject?: LibuildStyle['inject']; - /** - * The configuration of `tools.tailwindcss` is provided by `tailwindcss` plugin. - * Please use `yarn new` or `pnpm new` to enable the corresponding capability. - * @requires `tailwindcss` plugin - */ - tailwindcss?: TailwindCSSConfig; -} - -export interface StorybookBuildConfig { - webpack?: WebpackBuilderToolsConfig['webpack']; - webpackChain?: WebpackBuilderToolsConfig['webpackChain']; -} -export interface Dev { - storybook?: StorybookBuildConfig; -} - export interface RuntimeUserConfig { [name: string]: any; } diff --git a/packages/solutions/module-tools/src/types/config/style.ts b/packages/solutions/module-tools/src/types/config/style.ts index 6edd37bb0ed9..c54ea4386066 100644 --- a/packages/solutions/module-tools/src/types/config/style.ts +++ b/packages/solutions/module-tools/src/types/config/style.ts @@ -1,9 +1,74 @@ -import type { Style } from '@modern-js/libuild'; -import type { AcceptedPlugin as PostCSSPlugin } from 'postcss'; +import type { + AcceptedPlugin as PostCSSPlugin, + ProcessOptions, + Plugin, +} from 'postcss'; +import type { Options as sassOptions } from '../../../compiled/sass'; +import Less from '../../../compiled/less'; -export type LessOptions = Required