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: refine @okamjs/okam #1024

Merged
merged 1 commit into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading