Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: umd support mako bundler #750

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions examples/mako/.fatherrc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from '../../dist';
const path = require('path');

export default defineConfig({
umd: {
bundler: 'mako',
},
alias: {
'@': path.resolve(__dirname, './src'),
'hello-a': path.resolve(__dirname, './src/a.tsx'),
'hello-foo': path.resolve(__dirname, './src/foo.ts'),
},
platform: 'browser',
});
15 changes: 15 additions & 0 deletions examples/mako/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"scripts": {
"build": "father build",
"build:no-clean": "father build --no-clean",
"dev": "father dev",
"dev:no-clean": "father dev --no-clean",
"doctor": "father doctor",
"version": "father version"
},
"dependencies": {
"father": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
15 changes: 15 additions & 0 deletions examples/mako/src/a.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
console.log('hello here');

// @ts-ignore
import React from 'react';
// @ts-ignore
import ReactDOM from 'react-dom';

function App({content}:{content:string}) {
// @ts-ignore
return <div>{content}</div>;
}

// @ts-ignore
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App content={'hello'}/>);
7 changes: 7 additions & 0 deletions examples/mako/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();
1 change: 1 addition & 0 deletions examples/mako/src/foo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('foo here');
17 changes: 17 additions & 0 deletions examples/mako/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import content from '@/content';
import 'hello-a'
import 'hello-foo'
/*
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);
19 changes: 19 additions & 0 deletions examples/mako/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"skipLibCheck": true,
"target": "es2015",
"jsx": "react",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
19 changes: 15 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 35 additions & 11 deletions src/builder/bundle/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { webpack } from '@umijs/bundler-webpack';
import { chalk, importLazy, lodash } from '@umijs/utils';
import type { DevTool } from '@umijs/bundler-webpack/compiled/webpack-5-chain';
import { chalk, importLazy, lodash, tryPaths } from '@umijs/utils';
import assert from 'assert';
import path from 'path';
import { getCachePath, logger } from '../../utils';
import type { BundleConfigProvider } from '../config';
Expand All @@ -9,19 +11,22 @@ import {
getBundleTargets,
} from '../utils';

export interface IBundleWatcher {
close: () => void;
}

const bundler: typeof import('@umijs/bundler-webpack') = importLazy(
path.dirname(require.resolve('@umijs/bundler-webpack/package.json')),
);

const {
CSSMinifier,
JSMinifier,
}: typeof import('@umijs/bundler-webpack/dist/types') = importLazy(
require.resolve('@umijs/bundler-webpack/dist/types'),
);

export interface IBundleWatcher {
close: () => void;
}
const extensions = ['.js', '.jsx', '.ts', '.tsx', '.cjs', '.mjs'];

interface IBundleOpts {
cwd: string;
Expand Down Expand Up @@ -55,15 +60,15 @@ async function bundle(opts: IBundleOpts): Promise<void | IBundleWatcher> {

// log for normal build
!opts.watch && logStatus();
await bundler.build({
const options = {
cwd: opts.cwd,
watch: opts.watch,
config: {
alias: config.alias,
autoprefixer: config.autoprefixer,
chainWebpack: config.chainWebpack,
define: config.define,
devtool: config.sourcemap && 'source-map',
devtool: config.sourcemap && ('source-map' as DevTool),
externals: config.externals,
outputPath: config.output.path,

Expand Down Expand Up @@ -139,10 +144,11 @@ async function bundle(opts: IBundleOpts): Promise<void | IBundleWatcher> {

// also bundle svg as asset, because father force disable svgr
const imgRule = memo.module.rule('asset').oneOf('image');

imgRule.test(
new RegExp(imgRule.get('test').source.replace(/(\|png)/, '$1|svg')),
);
if (imgRule.get('test')) {
imgRule.test(
new RegExp(imgRule.get('test').source.replace(/(\|png)/, '$1|svg')),
);
}

// disable progress bar
memo.plugins.delete('progress-plugin');
Expand Down Expand Up @@ -180,7 +186,25 @@ async function bundle(opts: IBundleOpts): Promise<void | IBundleWatcher> {
}
: {}),
disableCopy: true,
});
};
if (process.env.OKAM && config.bundler === 'mako') {
require('@umijs/bundler-webpack/dist/requireHook');
const { build } = require(process.env.OKAM);

const entry = tryPaths(
extensions.map((ext) => path.join(opts.cwd, `${config.entry}${ext}`)),
) as string;

assert(entry, `Cannot find entry file ${config.entry}`);

options.entry = {
[path.parse(config.output.filename).name]: entry,
};

await build(options);
} else {
await bundler.build(options);
}
}

// return watching closer for watch mode
Expand Down
2 changes: 0 additions & 2 deletions src/builder/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export interface IBundleConfig
extends IFatherBaseConfig,
Omit<IFatherBundleConfig, 'entry' | 'output'> {
type: IFatherBuildTypes.BUNDLE;
bundler: 'webpack';
entry: string;
output: {
filename: string;
Expand Down Expand Up @@ -112,7 +111,6 @@ export function normalizeUserConfig(
typeof umd.output === 'object' ? umd.output : { path: umd.output };
const bundleConfig: Omit<IBundleConfig, 'entry'> = {
type: IFatherBuildTypes.BUNDLE,
bundler: 'webpack',
...baseConfig,

// override base configs from umd config
Expand Down
1 change: 1 addition & 0 deletions src/features/configPlugins/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export function getSchemas(): Record<string, (Joi: Root) => any> {
extractCSS: Joi.boolean().optional(),
name: Joi.string().optional(),
theme: Joi.object().pattern(Joi.string(), Joi.string()),
bundler: Joi.string().optional(),
}),
prebundle: (Joi) =>
Joi.object({
Expand Down
12 changes: 11 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import type { IConfig as IBundlerWebpackConfig } from '@umijs/bundler-webpack/di
import type { IAdd, IModify, IServicePluginAPI, PluginAPI } from '@umijs/core';
import type { ITransformerItem } from './builder/bundless/loaders/javascript';
import type {
createConfigProviders,
IBundleConfig,
IBundlessConfig,
createConfigProviders,
} from './builder/config';
import type { IDoctorReport } from './doctor';
import type { IDoctorSourceParseResult } from './doctor/parser';
Expand Down Expand Up @@ -91,6 +91,11 @@ export enum IFatherBundlessTypes {
CJS = 'cjs',
}

export enum IFatherBundlerTypes {
WEBPACK = 'webpack',
MAKO = 'mako',
}

export interface IFatherBaseConfig {
/**
* compile platform
Expand Down Expand Up @@ -216,6 +221,11 @@ export interface IFatherBundleConfig extends IFatherBaseConfig {
* configure less variables
*/
theme?: Record<string, string>;

/**
* configure bundler - webpack or mako
*/
bundler?: `${IFatherBundlerTypes}`;
}

export interface IFatherPreBundleConfig {
Expand Down
52 changes: 24 additions & 28 deletions tests/dev.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,34 +137,30 @@ test('dev: file change', async () => {
`export const ${content};`,
'utf-8',
);

await Promise.all([
// wait for watch debounce and compile
wait(WATCH_DEBOUNCE_STEP + 500),
// wait for webpack compilation done
new Promise<void>((resolve) => {
const logSpy = jest.spyOn(console, 'log');
const handler = () => {
try {
expect(console.log).toHaveBeenCalledWith(
// badge
expect.stringContaining('-'),
// time
expect.stringContaining('['),
// content
expect.stringContaining('Bundle '),
);
logSpy.mockRestore();
resolve();
} catch {
setTimeout(handler, 500);
}
};

handler();
}),
]);

// wait for watch debounce and compile
await wait(WATCH_DEBOUNCE_STEP + 500);
// wait for webpack compilation done
await new Promise<void>((resolve) => {
const logSpy = jest.spyOn(console, 'log');
const handler = () => {
try {
expect(console.log).toHaveBeenCalledWith(
// badge
expect.stringContaining('-'),
// time
expect.stringContaining('['),
// content
expect.stringContaining('Bundle '),
);
logSpy.mockRestore();
resolve();
} catch {
setTimeout(handler, 500);
}
};

handler();
});
const fileMap = distToMap(CASE_DIST);

expect(fileMap['esm/index.js']).toContain(content);
Expand Down