Skip to content

Commit

Permalink
feat: refine @okamjs/okam (#1024)
Browse files Browse the repository at this point in the history
  • Loading branch information
sorrycc authored Apr 7, 2024
1 parent c32194f commit 8023621
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 190 deletions.
24 changes: 24 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ await build({
root: process.cwd(),
config: {},
hooks: {},
less: {},
watch: false,
}: BuildOptions);
```
Expand All @@ -32,6 +33,29 @@ await build({

详见[配置](./config.md)

### less

- 类型:`Object`
- 默认值:`{}`

less 配置。

比如。

```ts
{
modifyVars: {
'primary-color': '#1DA57A',
'link-color': '#1DA57A',
},
sourceMap: {
sourceMapFileInline: true,
outputSourceFiles: true,
},
math: 'always',
}
```

### hooks

- 类型:
Expand Down
114 changes: 10 additions & 104 deletions packages/bundler-okam/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,56 +10,6 @@ const {
createProxyMiddleware,
} = require('@umijs/bundler-utils/compiled/http-proxy-middleware');

function lessLoader(fn, opts) {
return async function (filePath) {
let pathname = '';
try {
pathname = url.parse(filePath).pathname;
} catch (e) {
return;
}
if (pathname?.endsWith('.less')) {
const { alias, modifyVars, config, sourceMap } = opts;
const less = require('@umijs/bundler-utils/compiled/less');
const input = fs.readFileSync(pathname, 'utf-8');
const resolvePlugin = new (require('less-plugin-resolve'))({
aliases: alias,
});
const result = await less.render(input, {
filename: pathname,
javascriptEnabled: true,
math: config.lessLoader?.math,
plugins: [resolvePlugin],
modifyVars,
sourceMap,
rewriteUrls: 'all',
});
return { content: result.css, type: 'css' };
} else {
fn && fn(filePath);
}
};
}

// export for test only
exports._lessLoader = lessLoader;

// ref:
// https://github.com/vercel/next.js/pull/51883
function blockStdout() {
if (process.platform === 'darwin') {
// rust needs stdout to be blocking, otherwise it will throw an error (on macOS at least) when writing a lot of data (logs) to it
// see https://github.com/napi-rs/napi-rs/issues/1630
// and https://github.com/nodejs/node/blob/main/doc/api/process.md#a-note-on-process-io
if (process.stdout._handle != null) {
process.stdout._handle.setBlocking(true);
}
if (process.stderr._handle != null) {
process.stderr._handle.setBlocking(true);
}
}
}

exports.build = async function (opts) {
assert(opts, 'opts should be supplied');
const {
Expand All @@ -80,21 +30,15 @@ exports.build = async function (opts) {
okamConfig.moduleIdStrategy = 'hashed';
}

blockStdout();
const { build } = require('@okamjs/okam');
try {
await build({
root: cwd,
config: okamConfig,
hooks: {
load: lessLoader(null, {
cwd,
config: opts.config,
// NOTICE: 有个缺点是 如果 alias 配置是 mako 插件修改的 less 这边就感知到不了
alias: okamConfig.resolve.alias,
modifyVars: opts.config.lessLoader?.modifyVars || opts.config.theme,
sourceMap: getLessSourceMapConfig(okamConfig.devtool),
}),
less: {
modifyVars: opts.config.lessLoader?.modifyVars || opts.config.theme,
sourceMap: getLessSourceMapConfig(okamConfig.devtool),
math: opts.config.lessLoader?.math,
},
watch: false,
});
Expand Down Expand Up @@ -211,7 +155,6 @@ exports.dev = async function (opts) {
server.on('upgrade', wsProxy.upgrade);

// okam dev
blockStdout();
const { build } = require('@okamjs/okam');
const okamConfig = await getOkamConfig(opts);
okamConfig.hmr = { port: hmrPort, host: opts.host };
Expand All @@ -220,14 +163,12 @@ exports.dev = async function (opts) {
await build({
root: cwd,
config: okamConfig,
less: {
modifyVars: opts.config.lessLoader?.modifyVars || opts.config.theme,
sourceMap: getLessSourceMapConfig(okamConfig.devtool),
math: opts.config.lessLoader?.math,
},
hooks: {
load: lessLoader(null, {
cwd,
config: opts.config,
alias: okamConfig.resolve.alias,
modifyVars: opts.config.lessLoader?.modifyVars || opts.config.theme,
sourceMap: getLessSourceMapConfig(okamConfig.devtool),
}),
generateEnd: (args) => {
opts.onDevCompileDone(args);
},
Expand Down Expand Up @@ -451,16 +392,6 @@ async function getOkamConfig(opts) {
umd = webpackConfig.output.library;
}

let makoConfig = {};
const makoConfigPath = path.join(opts.cwd, 'mako.config.json');
if (fs.existsSync(makoConfigPath)) {
try {
makoConfig = JSON.parse(fs.readFileSync(makoConfigPath, 'utf-8'));
} catch (e) {
throw new Error(`Parse mako.config.json failed: ${e.message}`);
}
}

const {
alias,
targets,
Expand Down Expand Up @@ -541,7 +472,6 @@ async function getOkamConfig(opts) {
// handle [string] with script type
if (Array.isArray(v)) {
const [url, ...members] = v;

ret[k] = {
// ['antd', 'Button'] => `antd.Button`
root: members.join('.'),
Expand All @@ -555,33 +485,14 @@ async function getOkamConfig(opts) {
// other types except boolean has been checked before
// so here only ignore invalid boolean type
}

return ret;
}, {});

const okamConfig = {
entry: opts.entry,
output: { path: outputPath },
resolve: {
alias: {
...alias,
...makoConfig.resolve?.alias,
// we still need @swc/helpers
// since features like decorator or legacy browser support will
// inject helper functions in the build transform step
'@swc/helpers': path.dirname(
require.resolve('@swc/helpers/package.json'),
),
'node-libs-browser-okam': path.dirname(
require.resolve('node-libs-browser-okam/package.json'),
),
'react-refresh': path.dirname(
require.resolve('react-refresh/package.json'),
),
'react-error-overlay': path.dirname(
require.resolve('react-error-overlay/package.json'),
),
},
alias,
},
mode: 'development',
publicPath: runtimePublicPath ? 'runtime' : publicPath || '/',
Expand All @@ -605,11 +516,6 @@ async function getOkamConfig(opts) {
...(opts.disableCopy ? { copy: [] } : { copy: ['public'].concat(copy) }),
};

if (process.env.DUMP_MAKO_CONFIG) {
const configFile = path.join(process.cwd(), 'mako.config.json');
fs.writeFileSync(configFile, JSON.stringify(okamConfig, null, 2));
}

return okamConfig;
}

Expand Down
4 changes: 0 additions & 4 deletions packages/bundler-okam/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@
"version": "0.4.9",
"dependencies": {
"@okamjs/okam": "0.4.9",
"@swc/helpers": "0.5.1",
"@umijs/bundler-utils": "^4.0.81",
"chalk": "^4.1.2",
"compression": "^1.7.4",
"connect-history-api-fallback": "^2.0.0",
"cors": "^2.8.5",
"express": "^4.18.2",
"less-plugin-resolve": "^1.0.2",
"lodash": "^4.17.21",
"node-libs-browser-okam": "2.2.4",
"react-error-overlay": "6.0.9",
"react-refresh": "^0.14.0",
"rimraf": "5.0.1",
"webpack-5-chain": "8.0.1"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/mako/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@
}
},
"license": "MIT",
"dependencies": {
"@swc/helpers": "0.5.1",
"less": "^4.2.0",
"less-plugin-resolve": "^1.0.2",
"react-error-overlay": "6.0.9",
"react-refresh": "^0.14.0"
},
"devDependencies": {
"@types/less": "^3.0.6",
"@types/node": "^20.12.5",
"@napi-rs/cli": "^2.18.0"
},
"engines": {
Expand Down
93 changes: 92 additions & 1 deletion packages/mako/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,92 @@
export * from '../binding';
import fs from 'fs';
import path from 'path';
import * as binding from '../binding';
import { LessLoaderOpts, lessLoader } from './lessLoader';

// ref:
// https://github.com/vercel/next.js/pull/51883
function blockStdout() {
if (process.platform === 'darwin') {
// rust needs stdout to be blocking, otherwise it will throw an error (on macOS at least) when writing a lot of data (logs) to it
// see https://github.com/napi-rs/napi-rs/issues/1630
// and https://github.com/nodejs/node/blob/main/doc/api/process.md#a-note-on-process-io
if ((process.stdout as any)._handle != null) {
(process.stdout as any)._handle.setBlocking(true);
}
if ((process.stderr as any)._handle != null) {
(process.stderr as any)._handle.setBlocking(true);
}
}
}

interface ExtraBuildParams {
less?: LessLoaderOpts;
}

export async function build(params: binding.BuildParams & ExtraBuildParams) {
blockStdout();

params.hooks = params.hooks || {};
params.config.resolve = params.config.resolve || {};
params.config.resolve.alias = params.config.resolve.alias || {};

let makoConfig: any = {};
const makoConfigPath = path.join(params.root, 'mako.config.json');
if (fs.existsSync(makoConfigPath)) {
try {
makoConfig = JSON.parse(fs.readFileSync(makoConfigPath, 'utf-8'));
} catch (e: any) {
throw new Error(`Parse mako.config.json failed: ${e.message}`);
}
}

// alias for: helpers, node-libs, react-refresh, react-error-overlay
params.config.resolve.alias = {
...makoConfig.resolve?.alias,
...params.config.resolve.alias,
// we still need @swc/helpers
// since features like decorator or legacy browser support will
// inject helper functions in the build transform step
'@swc/helpers': path.dirname(require.resolve('@swc/helpers/package.json')),
'node-libs-browser-okam': path.dirname(
require.resolve('node-libs-browser-okam/package.json'),
),
'react-refresh': path.dirname(
require.resolve('react-refresh/package.json'),
),
'react-error-overlay': path.dirname(
require.resolve('react-error-overlay/package.json'),
),
};

// built-in less-loader
let less = lessLoader(null, {
alias: params.config.resolve.alias!,
modifyVars: params.less?.modifyVars || {},
math: params.less?.math,
sourceMap: params.less?.sourceMap || false,
});
let originLoad = params.hooks.load;
// TODO: improve load binding, should support return null if not matched
// @ts-ignore
params.hooks.load = async function (filePath: string) {
let lessResult = await less(filePath);
if (lessResult) {
return lessResult;
}
if (originLoad) {
let originResult = await originLoad(filePath);
if (originResult) {
return originResult;
}
}
};

// support dump mako config
if (process.env.DUMP_MAKO_CONFIG) {
const configFile = path.join(params.root, 'mako.config.json');
fs.writeFileSync(configFile, JSON.stringify(params.config, null, 2));
}

await binding.build(params);
}
Loading

0 comments on commit 8023621

Please sign in to comment.