Skip to content

Commit

Permalink
fix: compile all deps when specify deps in compileDependencies (#602)
Browse files Browse the repository at this point in the history
* fix: compile all deps when specify deps in compileDependencies

* chore: changeset

* refactor: compileDependencies

* chore: remove comment

* feat: optimize

* fix: test

* feat: add test

* fix: not compile polyfills and helpers

* fix: type

* fix: comment

* fix: include node_modules scripts
  • Loading branch information
luhc228 authored Oct 16, 2023
1 parent ff11dad commit ac854dd
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/giant-wolves-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ice/pkg': patch
---

fix: compile all deps when specify deps in compileDependencies
6 changes: 3 additions & 3 deletions packages/pkg/src/rollupPlugins/babel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import * as babel from '@babel/core';
import type { ParserPlugin } from '@babel/parser';
import { Plugin } from 'rollup';
import { createScriptsFilter } from '../utils.js';
import { createScriptsFilter, formatCnpmDepFilepath, getIncludeNodeModuleScripts } from '../utils.js';
import type { BundleTaskConfig } from '../types.js';
import { TransformOptions } from '@babel/core';
import getBabelOptions from '../helpers/getBabelOptions.js';
Expand Down Expand Up @@ -43,12 +43,12 @@ const babelPlugin = (
): Plugin => {
// https://babeljs.io/docs/en/babel-preset-react#usage
const babelOptions = getBabelOptions(plugins, options, modifyBabelOptions);
const scriptsFilter = createScriptsFilter(compileDependencies);
const scriptsFilter = createScriptsFilter(getIncludeNodeModuleScripts(compileDependencies));
return {
name: 'ice-pkg:babel',

transform(source, id) {
if (!scriptsFilter(id)) {
if (!scriptsFilter(formatCnpmDepFilepath(id))) {
return null;
}

Expand Down
8 changes: 5 additions & 3 deletions packages/pkg/src/rollupPlugins/swc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { extname, basename, relative, sep } from 'path';
import * as swc from '@swc/core';
import deepmerge from 'deepmerge';
import { isTypescriptOnly } from '../helpers/suffix.js';
import { checkDependencyExists, createScriptsFilter } from '../utils.js';
import { checkDependencyExists, createScriptsFilter, formatCnpmDepFilepath, getIncludeNodeModuleScripts } from '../utils.js';

import type { Options as swcCompileOptions, Config, TsParserConfig, EsParserConfig } from '@swc/core';
import type { TaskConfig, OutputFile, BundleTaskConfig } from '../types.js';
Expand Down Expand Up @@ -65,12 +65,14 @@ const swcPlugin = (
extraSwcOptions?: Config,
compileDependencies?: BundleTaskConfig['compileDependencies'],
): Plugin => {
const scriptsFilter = createScriptsFilter(compileDependencies);
const scriptsFilter = createScriptsFilter(
getIncludeNodeModuleScripts(compileDependencies),
);
return {
name: 'ice-pkg:swc',

async transform(source, id) {
if (!scriptsFilter(id)) {
if (!scriptsFilter(formatCnpmDepFilepath(id))) {
return null;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/pkg/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export interface BundleUserConfig {
/**
* Weather or not compile the dependencies in node_modules.
*/
compileDependencies?: boolean | RegExp[];
compileDependencies?: boolean | Array<RegExp | string>;
}

export interface UserConfig {
Expand Down
64 changes: 54 additions & 10 deletions packages/pkg/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,18 +286,62 @@ export const stringifyObject = (obj: PlainObject) => {
}, {});
};

export const createScriptsFilter = (compileDependencies?: boolean | RegExp[]) => {
const exclude = [/\.d\.ts$/];
if (Array.isArray(compileDependencies)) {
exclude.push(...compileDependencies);
} else if (!compileDependencies) {
exclude.push(/node_modules/);
// @ref: It will pass to createScriptFilter function
export function getIncludeNodeModuleScripts(compileDependencies: boolean | Array<RegExp | string>): RegExp[] {
if (compileDependencies === true || (Array.isArray(compileDependencies) && compileDependencies.length === 0)) {
return [/node_modules/];
}
return createFilter(
/\.m?[jt]sx?$/, // include
exclude,
);
if (Array.isArray(compileDependencies) && compileDependencies.length > 0) {
// compile all deps in node_modules except compileDependencies
// for example: now only want to compile abc and @ice/abc deps.
// will generate the regular expression: /node_modules(?:\/|\\\\)(abc|@ice\/abc)(?:\/|\\\\)(?!node_modules).*/
// will match:
// 1. node_modules/abc/index.js
// 2. node_modules/def/node_modules/abc/index.js
// 3. node_modules/@ice/abc/index.js
// 4. node_modules/def/node_modules/@ice/abc/index.js
// will not match:
// node_modules/abc/node_modules/def/index.js
// node_modules/def/index.js
return [new RegExp(`node_modules/(${compileDependencies.map((dep: string | RegExp) => (`${typeof dep === 'string' ? dep : dep.source}`)).join('|')})/(?!node_modules).*.m?[jt]sx?$`)];
}
// default
return [];
}

/**
* @reason cnpm node_modules path is different from npm/pnpm, it will not match the compileDependencies
*
* @example transform react/node_modules/[email protected]@idb/build/index.js to react/node_modules/idb/build/index.js
*/
export function formatCnpmDepFilepath(filepath: string) {
const reg = /(.*(?:\/|\\\\))(?:_.*@(?:\d+)\.(?:\d+)\.(?:\d+)(?:-(?:(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?:[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?@)(.*)/;
const matchedResult = filepath.match(reg);
if (!matchedResult) {
return filepath;
}
const [, p1, p2] = matchedResult;
return p1 + p2;
}

/**
* default include src/**.m?[jt]sx? but exclude .d.ts file
*
* @param extraInclude include other file types
* @param extraExclude exclude other file types
*
* @example exclude node_modules createScriptsFilter([], [/node_modules/])
*/
export const createScriptsFilter = (
extraIncludes: RegExp[] = [],
extraExcludes: RegExp[] = [],
) => {
const includes = [/src\/.*\.m?[jt]sx?$/].concat(extraIncludes);
const excludes = [/\.d\.ts$/, /core-js/, /core-js-pure/, /tslib/, /@swc\/helpers/, /@babel\/runtime/, /babel-runtime/].concat(extraExcludes);

return createFilter(includes, excludes);
};

export const cwd = process.cwd();

export function normalizeSlashes(file: string) {
Expand Down
4 changes: 2 additions & 2 deletions packages/pkg/tests/babelPlugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('transform', () => {
});
expect(babelPlugin.name).toBe('ice-pkg:babel');
// @ts-ignore it's callable
const ret = babelPlugin.transform('<div x-if={false}></div>', 'test.tsx');
const ret = babelPlugin.transform('<div x-if={false}></div>', 'src/test.tsx');
expect(cleanCode(ret.code)).toBe(
cleanCode(`import { createCondition as __create_condition__ } from "babel-runtime-jsx-plus";
import { jsx as _jsx } from "react/jsx-runtime";
Expand All @@ -55,7 +55,7 @@ describe('transform', () => {
});
expect(babelPlugin.name).toBe('ice-pkg:babel');
// @ts-ignore it's callable
const ret = babelPlugin.transform('<div x-if={false}></div>', 'test.tsx');
const ret = babelPlugin.transform('<div x-if={false}></div>', 'src/test.tsx');
expect(cleanCode(ret.code)).toBe(
cleanCode(`import { createCondition as __create_condition__ } from "babel-runtime-jsx-plus";
__create_condition__([[() => false, () => /*#__PURE__*/React.createElement("div", null)]]);`),
Expand Down
23 changes: 23 additions & 0 deletions packages/pkg/tests/formatCnpmDepFilepath.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { expect, it, describe } from 'vitest';
import { formatCnpmDepFilepath } from '../src/utils';

describe('formatCnpmDepFilepath function', () => {
it('pnpm path', () => {
expect(formatCnpmDepFilepath('/workspace/node_modules/.pnpm/[email protected]/node_modules/classnames/index.js')).toBe('/workspace/node_modules/.pnpm/[email protected]/node_modules/classnames/index.js');
})
it('pnpm path with scope', () => {
expect(formatCnpmDepFilepath('/workspace/node_modules/.pnpm/@[email protected]/node_modules/@actions/exec/lib/exec.js')).toBe('/workspace/node_modules/.pnpm/@[email protected]/node_modules/@actions/exec/lib/exec.js');
})
it('cnpm path', () => {
expect(formatCnpmDepFilepath('/workspace/node_modules/[email protected]@idb/build/index.js')).toBe('/workspace/node_modules/idb/build/index.js');
})
it('cnpm path with npm scope', () => {
expect(formatCnpmDepFilepath('/workspace/node_modules/_@[email protected]@@swc/helpers/esm/_extends.js')).toBe('/workspace/node_modules/@swc/helpers/esm/_extends.js');
})
it('npm path', () => {
expect(formatCnpmDepFilepath('/workspace/node_modules/idb/build/index.js')).toBe('/workspace/node_modules/idb/build/index.js');
})
it('npm path with npm scope', () => {
expect(formatCnpmDepFilepath('/workspace/node_modules/@ice/idb/build/index.js')).toBe('/workspace/node_modules/@ice/idb/build/index.js');
})
})
4 changes: 2 additions & 2 deletions website/docs/reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ export default defineConfig({

#### compileDependencies

+ 类型:`boolean | RegExp[]`
+ 类型:`boolean | RegExp[] | string[]`
+ 默认值:`false`

配置是否编译 node_modules 中的依赖。如果值为 `true`,则 node_modules 中的依赖都会编译;如果值为 false 则都不编译;如果值为数组,则只会编译对应的依赖。
Expand All @@ -453,7 +453,7 @@ import { defineConfig } from '@ice/pkg';

export default defineConfig({
bundle: {
compileDependencies: [/antd/],
compileDependencies: ['antd'],
},
});
```
Expand Down

0 comments on commit ac854dd

Please sign in to comment.