Skip to content

Commit

Permalink
refactor: build tools (nocobase#2374)
Browse files Browse the repository at this point in the history
* refactor: core/build and cli/build.js

* fix: build

* fix: bug

* fix: replaceAll to replace

* fix: node version check

* fix: add require check

* fix: esbuild other ext

* fix: process json

* fix: exlude jsx-runtime

* feat: split chunk

* fix: minify plugin client bundle

* fix: compatibility

* fix: support import()

* feat: update docs

* fix: server deps

* feat: demo

* fix: remove cjs treeshake

* fix: local error

* fix: bug

* fix: lazy load

* fix: rewrites

* fix: remove dynamic import  function

* feat: doc demo

* fix: codesanbox vite template

* fix: codesanbox demo

* fix: hide stackblitz

* fix: revert rspack

* fix: test bug

* fix: delete console

* fix: import dayjs locale

---------

Co-authored-by: chenos <[email protected]>
  • Loading branch information
dream2023 and chenos authored Sep 3, 2023
1 parent 24179c4 commit 08c5383
Show file tree
Hide file tree
Showing 471 changed files with 2,333 additions and 8,138 deletions.
11 changes: 0 additions & 11 deletions .buildrc.ts

This file was deleted.

221 changes: 221 additions & 0 deletions .dumi/theme/slots/PreviewerActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import DumiPreviewerActions from 'dumi/theme-default/slots/PreviewerActions';
import React, { useRef, useEffect, useState } from 'react';
import { Spin } from 'antd'

import { IPreviewerProps } from 'dumi';

const indexHtml = `<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
`

const mainTsx = `
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
`

const packageJson = `
{
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
},
"devDependencies": {
"flat": "^5.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.0.3",
"less": "^4.2.0",
"typescript": "^5.0.2",
"vite": "^4.4.5"
}
}
`

const tsConfigJson = `
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"composite": true,
"strict": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"allowSyntheticDefaultImports": true,
"noFallthroughCasesInSwitch": true
},
"include": [
"src",
"vite.config.ts"
]
}
`

const viteConfigTs = `
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})
`

const sandboxTask = `
{
"setupTasks": [
{
"name": "Install Dependencies",
"command": "yarn install"
}
],
"tasks": {
"dev": {
"name": "dev",
"command": "yarn dev",
"runAtStart": true,
"preview": {
"port": 5173
}
},
"build": {
"name": "build",
"command": "yarn build",
"runAtStart": false
},
"preview": {
"name": "preview",
"command": "yarn preview",
"runAtStart": false
}
}
}
`

function getCSBData(opts: IPreviewerProps, ext: string) {

const files: Record<
string,
{
content: string;
isBinary: boolean;
}
> = {};
const deps: Record<string, string> = {};
const entryFileName = `index${ext}`;

Object.entries(opts.asset.dependencies).forEach(([name, { type, value }]) => {
if (type === 'NPM') {
// generate dependencies
deps[name] = value;
} else {
// append other imported local files
files[name === entryFileName ? `src/App${ext}` : name] = {
content: value,
isBinary: false,
};
}
});

// append package.json
let pkg = JSON.parse(packageJson)
try {
for (let key in deps) {
if (!pkg['devDependencies'][key]) {
pkg.dependencies[key] = deps[key]
}
}
} catch (e) {
console.log(e)
}
files['package.json'] = {
content: JSON.stringify(
{
name: opts.title,
...pkg,
},
null,
2,
),
isBinary: false,
};

files['index.html'] = { content: indexHtml, isBinary: false };
files['src/main.tsx'] = { content: mainTsx, isBinary: false };
files['package.json'] = { content: JSON.stringify(pkg, null, 2), isBinary: false };
files['.codesandbox/task.json'] = { content: sandboxTask, isBinary: false };
files['tsconfig.json'] = { content: tsConfigJson, isBinary: false };
files['vite.config.ts'] = { content: viteConfigTs, isBinary: false };

return { files };
}


export function openCodeSandbox(opts: IPreviewerProps) {
const isTSX = Boolean(opts.asset.dependencies?.['index.tsx']);
const ext = isTSX ? '.tsx' : '.jsx';
return fetch("https://codesandbox.io/api/v1/sandboxes/define?json=1", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(getCSBData(opts, ext))
})
.then(x => x.json())
.then(data => {
window.open(`https://codesandbox.io/p/sandbox/${data.sandbox_id}?file=/src/App${ext}`);
});
}


const PreviewerActions: typeof DumiPreviewerActions = (props) => {
const div = useRef<HTMLDivElement>(null);
const [loading, setLoading] = useState(false);

useEffect(() => {
if (div.current) {
const elements = div.current.querySelectorAll('.dumi-default-previewer-actions');
elements.forEach((element) => {
element.addEventListener('click', (e) => {
e.stopImmediatePropagation();
setLoading(true);
openCodeSandbox(props).finally(() => {
setLoading(false);
});
})
})
}
}, [div])

return <Spin spinning={loading}><div ref={div}><DumiPreviewerActions {...props} disabledActions={['STACKBLITZ']} /></div></Spin>
};

export default PreviewerActions;
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"packages/*/*"
],
"license": "Apache-2.0",
"engines": {
"node": ">=16.0.0"
},
"licenses": [
{
"type": "Apache-2.0",
Expand Down
1 change: 0 additions & 1 deletion packages/app/client/src/plugins/api-doc.ts

This file was deleted.

6 changes: 4 additions & 2 deletions packages/core/acl/src/snippet-manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ACL } from './acl';
import minimatch from 'minimatch';

export type SnippetOptions = {
Expand All @@ -7,7 +6,10 @@ export type SnippetOptions = {
};

class Snippet {
constructor(public name: string, public actions: Array<string>) {}
constructor(
public name: string,
public actions: Array<string>,
) {}
}

export type SnippetGroup = {
Expand Down
7 changes: 6 additions & 1 deletion packages/core/app/client/.umirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ process.env.MFSU_AD = 'none';
process.env.DID_YOU_KNOW = 'none';

const pluginPrefix = (process.env.PLUGIN_PACKAGE_PREFIX || '').split(',').filter((item) => !item.includes('preset')); // 因为现在 preset 是直接引入的,所以不能忽略,如果以后 preset 也是动态插件的形式引入,那么这里可以去掉
const pluginDirs = 'packages/plugins/,packages/samples/'.split(',').map((item) => path.join(process.cwd(), item));

const pluginDirs = (process.env.PLUGIN_PATH || 'packages/plugins/,packages/samples/')
.split(',').map(item => path.join(__dirname, '..', '..', '..', '..', item));

const outputPluginPath = path.join(__dirname, 'src', '.plugins');
const indexGenerator = new IndexGenerator(outputPluginPath, pluginDirs);
Expand Down Expand Up @@ -51,6 +53,9 @@ export default defineConfig({
edge: 79,
safari: 12,
},
codeSplitting: {
jsStrategy: 'depPerChunk'
},
chainWebpack(config, { env }) {
if (env === 'production') {
config.plugin('ignore nocobase plugins').use(require('webpack').IgnorePlugin, [
Expand Down
1 change: 0 additions & 1 deletion packages/core/build/.local

This file was deleted.

46 changes: 2 additions & 44 deletions packages/core/build/bin/nocobase-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { existsSync } = require('fs');
const { join } = require('path');
const yParser = require('yargs-parser');
const chalk = require('chalk');
const signale = require('signale');
const { build } = require('../lib');

// print version and @local
const args = yParser(process.argv.slice(2), {
Expand All @@ -26,46 +26,4 @@ const updater = require('update-notifier');
const pkg = require('../package.json');
updater({ pkg }).notify({ defer: true });

function stripEmptyKeys(obj) {
Object.keys(obj).forEach((key) => {
if (!obj[key] || (Array.isArray(obj[key]) && !obj[key].length)) {
delete obj[key];
}
});
return obj;
}

function build() {
// Parse buildArgs from cli
const buildArgs = stripEmptyKeys({
esm: args.esm && { type: args.esm === true ? 'rollup' : args.esm },
cjs: args.cjs && { type: args.cjs === true ? 'rollup' : args.cjs },
umd: args.umd && { name: args.umd === true ? undefined : args.umd },
file: args.file,
target: args.target,
entry: args._,
config: args.config,
});

if (buildArgs.file && buildArgs.entry && buildArgs.entry.length > 1) {
signale.error(
new Error(`Cannot specify file when have multiple entries (${buildArgs.entry.join(', ')})`)
);
process.exit(1);
}

require('../lib/build')
.default({
cwd: args.root || process.cwd(),
watch: args.w || args.watch,
clean: args.clean,
buildArgs,
packages: args._ || [],
})
.catch((e) => {
signale.error(e);
process.exit(1);
});
}

build();
build(args._);
Loading

0 comments on commit 08c5383

Please sign in to comment.