Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Commit

Permalink
feat: add babel transformer
Browse files Browse the repository at this point in the history
patch from umijs/umi-next#580

* feat(father): add babel transformer

* example(father): test babel transformer

* chore: remove unused code

* chore(father): update pnpm-lock

* feat(father): replace babel-plugin with @umijs/babel-preset-umi
  • Loading branch information
lylwanan authored and PeachScript committed Jun 10, 2022
1 parent 2a69b6e commit c98d1b2
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 16 deletions.
13 changes: 12 additions & 1 deletion examples/normal/.fatherrc.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
const path = require('path');

export default {
esm: {},
esm: {
output: 'dist/esm',
},
umd: {
output: 'dist/umd',
},
alias: {
'@': path.resolve(__dirname, './src'),
},
platform: 'browser',
};
7 changes: 7 additions & 0 deletions examples/normal/src/content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Content {
say() {
return 'Hello father 3';
}
}

export default new Content().say();
16 changes: 15 additions & 1 deletion examples/normal/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
export default 'Hello father 3';
import content from '@/content';
/*
import React from 'react';
import ReactDOM from 'react-dom';
// const content = 'Hello'
function App() {
return <div>{content}</div>;
}
// @ts-ignore
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
*/
console.log(content);
18 changes: 18 additions & 0 deletions examples/normal/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"skipLibCheck": true,
"target": "es2015",
"jsx": "react",
"paths": {
"@/*": ["./src/*"]
}
}
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
"@umijs/bundler-webpack": "^4.0.0-beta.1",
"@umijs/core": "^4.0.0-beta.1",
"@umijs/utils": "^4.0.0-beta.1",
"babel-plugin-module-resolver": "4.1.0",
"babel-plugin-react-require": "3.1.3",
"babel-plugin-transform-define": "2.0.1",
"loader-runner": "4.2.0",
"minimatch": "3.1.2",
"v8-compile-cache": "2.3.0"
Expand Down
12 changes: 10 additions & 2 deletions src/builder/bundless/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export default async (opts: {
ignore: DEFAULT_BUNDLESS_IGNORES,
nodir: true,
});
const babelTransformRegexp = /\.(t|j)sx?$/;

function isTransform(path: string) {
return babelTransformRegexp.test(path) && !path.endsWith('.d.ts');
}

// process all matched items
for (let item of matches) {
Expand All @@ -35,7 +40,7 @@ export default async (opts: {
config.output!,
path.relative(config.input, item),
);
const itemDistAbsPath = path.join(opts.cwd, itemDistPath);
let itemDistAbsPath = path.join(opts.cwd, itemDistPath);
const parentPath = path.dirname(itemDistAbsPath);

// create parent directory if not exists
Expand All @@ -44,7 +49,10 @@ export default async (opts: {
}

// get result from loaders
const result = await runLoaders(item, config);
const result = await runLoaders(item, { ...config });
itemDistAbsPath = isTransform(itemDistAbsPath)
? itemDistAbsPath.replace(path.extname(itemDistAbsPath), '.js')
: itemDistAbsPath;

if (result) {
// distribute file with result
Expand Down
2 changes: 1 addition & 1 deletion src/builder/bundless/loaders/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default async (fileAbsPath: string, config: IBundlessConfig) => {
{
resource: fileAbsPath,
loaders: [{ loader: matched.loader, options: matched.options }],
context: { config },
context: { config, fileAbsPath },
readResource: fs.readFile.bind(fs),
},
(err, { result }) => {
Expand Down
60 changes: 55 additions & 5 deletions src/builder/bundless/loaders/javascript/babel.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,70 @@
import { IFatherJSTransformerTypes } from '../../../../types';
import {
transform as babelTransform,
TransformOptions,
} from '@umijs/bundler-utils/compiled/babel/core';
import {
IFatherJSTransformerTypes,
IFatherPlatformTypes,
} from '../../../../types';
import type { IBundlessConfig } from '../../../config';
import resolvePath from './resolvePath';

/**
* babel transformer
*/
class BabelTransformer {
static id = IFatherJSTransformerTypes.BABEL;

config = {} as TransformOptions;

constructor(config: IBundlessConfig) {
config;
// TODO: create babel instance from config
this.config = this.getBabelConfig(config);
}

process(content: string) {
// TODO: transform content
return content;
getBabelConfig(config: IBundlessConfig): TransformOptions {
const { platform, extraBabelPlugins, extraBabelPresets, define, alias } =
config;
const isBrowser = platform === IFatherPlatformTypes.BROWSER;

return {
presets: [
[
require.resolve('@umijs/babel-preset-umi'),
{
presetEnv: {},
presetReact: {},
presetTypeScript: {},
pluginTransformRuntime: {},
pluginLockCoreJS: {},
pluginAutoCSSModules: false,
pluginDynamicImportNode: false,
},
],
...(extraBabelPresets ? extraBabelPresets : []),
],
plugins: [
[require.resolve('babel-plugin-transform-define'), define || {}],
isBrowser && [require.resolve('babel-plugin-react-require')],
[
require.resolve('babel-plugin-module-resolver'),
{
alias: alias || {},
resolvePath,
},
],
...(extraBabelPlugins ? extraBabelPlugins : []),
].filter(Boolean),
};
}

process(content: string, fileAbsPath: string) {
const config = this.config;

return babelTransform(content, {
filename: fileAbsPath,
...config,
})?.code;
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/builder/bundless/loaders/javascript/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export function addTransformer(transformer: ITransformer) {
*/
const jsLoader: ILoader = function (content) {
const transformer = new transformers[this.config.transformer!](this.config);

return transformer.process(content);
return transformer.process(content, this.fileAbsPath);
};

export default jsLoader;
79 changes: 79 additions & 0 deletions src/builder/bundless/loaders/javascript/resolvePath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// @ts-ignore
import mapToRelative from 'babel-plugin-module-resolver/lib/mapToRelative';
// @ts-ignore
import normalizeOptions from 'babel-plugin-module-resolver/lib/normalizeOptions';
// @ts-ignore
import resolvePath from 'babel-plugin-module-resolver/lib/resolvePath';
// @ts-ignore
import * as utils from 'babel-plugin-module-resolver/lib/utils';
import path from 'path';

interface INormalizeOptions {
cwd: string;
extensions: Array<string>;
alias: Array<[RegExp, Function]>;
}

function resolvePathFromAliasConfig(
sourcePath: string,
currentFile: string,
opts: Record<string, object>,
) {
if (utils.isRelativePath(sourcePath)) {
return sourcePath;
}

const normalizedOpts: INormalizeOptions = normalizeOptions(currentFile, opts);

const absoluteCurrentFile = path.resolve(currentFile);

let aliasedSourceFile!: Array<string>;
normalizedOpts.alias.find(([regExp, substitute]) => {
const execResult = regExp.exec(sourcePath);

if (execResult === null) {
return false;
}

aliasedSourceFile = substitute(execResult);
return true;
});

if (!aliasedSourceFile) {
return resolvePath(sourcePath, absoluteCurrentFile, normalizedOpts);
}

if (Array.isArray(aliasedSourceFile)) {
return aliasedSourceFile
.map((asf) => {
if (utils.isRelativePath(asf)) {
return utils.toLocalPath(
utils.toPosixPath(
mapToRelative.default(
normalizedOpts.cwd,
absoluteCurrentFile,
asf,
),
),
);
}

return asf;
})
.find((src) =>
utils.nodeResolvePath(
src,
path.dirname(absoluteCurrentFile),
normalizedOpts.extensions,
),
);
}

return utils.toLocalPath(
utils.toPosixPath(
mapToRelative(normalizedOpts.cwd, absoluteCurrentFile, aliasedSourceFile),
),
);
}

export default resolvePathFromAliasConfig;
6 changes: 5 additions & 1 deletion src/builder/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import type { IBundlessConfig } from './config';
* normal loader type (base on webpack loader)
*/
export type ILoader = (
this: ExtendedLoaderContext & { config: IBundlessConfig },
this: ExtendedLoaderContext & {
config: IBundlessConfig;
fileAbsPath: string;
},
content: RunLoaderResult['resourceBuffer'],
) => typeof content;

Expand All @@ -26,5 +29,6 @@ export interface ITransformer {
*/
process: (
content: RunLoaderResult['resourceBuffer'],
fileAbsPath: string,
) => RunLoaderResult['resourceBuffer'];
}
6 changes: 3 additions & 3 deletions src/features/configBuilder/configBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { addTransformer as addJSTransformer } from '../../builder/bundless/loaders/javascript';
import {
addLoader as addBundlessLoader,
type ILoaderItem,
ILoaderItem,
} from '../../builder/bundless/loaders';
import { addTransformer as addJSTransformer } from '../../builder/bundless/loaders/javascript';
import babel from '../../builder/bundless/loaders/javascript/babel';
import esbuild from '../../builder/bundless/loaders/javascript/esbuild';
import type { IApi } from '../../types';
import type { ITransformer } from '../../builder/protocol';
import type { IApi } from '../../types';

export default async (api: IApi) => {
// collect all bundless loaders
Expand Down

0 comments on commit c98d1b2

Please sign in to comment.