mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-01 19:58:15 +08:00
refactor: build tools (#2374)
* 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 <chenlinxh@gmail.com>
This commit is contained in:
parent
24179c4469
commit
08c5383bee
11
.buildrc.ts
11
.buildrc.ts
@ -1,11 +0,0 @@
|
||||
export default {
|
||||
target: 'node',
|
||||
cjs: { type: 'babel', lazy: true },
|
||||
excludePkgs: [
|
||||
'core/build',
|
||||
'core/cli',
|
||||
'core/create-nocobase-app',
|
||||
'core/devtools',
|
||||
'app/client',
|
||||
],
|
||||
};
|
221
.dumi/theme/slots/PreviewerActions.tsx
Normal file
221
.dumi/theme/slots/PreviewerActions.tsx
Normal file
@ -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;
|
@ -5,6 +5,9 @@
|
||||
"packages/*/*"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache-2.0",
|
||||
|
@ -1 +0,0 @@
|
||||
export { default } from '@nocobase/plugin-api-doc/client';
|
@ -1,4 +1,3 @@
|
||||
import { ACL } from './acl';
|
||||
import minimatch from 'minimatch';
|
||||
|
||||
export type SnippetOptions = {
|
||||
@ -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 = {
|
||||
|
@ -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);
|
||||
@ -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, [
|
||||
|
@ -1 +0,0 @@
|
||||
Used in bin/father.js to determine if it is in the local debug state.
|
@ -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), {
|
||||
@ -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._);
|
||||
|
@ -8,76 +8,33 @@
|
||||
},
|
||||
"typings": "./index.d.ts",
|
||||
"dependencies": {
|
||||
"@babel/core": "7.22.5",
|
||||
"@babel/plugin-proposal-class-properties": "7.18.6",
|
||||
"@babel/plugin-proposal-decorators": "7.22.5",
|
||||
"@babel/plugin-proposal-do-expressions": "7.22.5",
|
||||
"@babel/plugin-proposal-export-default-from": "7.22.5",
|
||||
"@babel/plugin-proposal-export-namespace-from": "7.18.9",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.21.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.22.5",
|
||||
"@babel/plugin-transform-runtime": "7.22.5",
|
||||
"@babel/preset-env": "7.12.1",
|
||||
"@babel/preset-react": "7.22.5",
|
||||
"@babel/preset-typescript": "7.22.5",
|
||||
"@babel/register": "7.22.5",
|
||||
"@hapi/topo": "^6.0.0",
|
||||
"@lerna/filter-packages": "4.0.0",
|
||||
"@lerna/project": "4.0.0",
|
||||
"@lerna/query-graph": "4.0.0",
|
||||
"@rollup/plugin-babel": "6.0.3",
|
||||
"@rollup/plugin-commonjs": "25.0.1",
|
||||
"@rollup/plugin-inject": "5.0.3",
|
||||
"@rollup/plugin-json": "6.0.0",
|
||||
"@rollup/plugin-node-resolve": "15.1.0",
|
||||
"@rollup/plugin-replace": "5.0.2",
|
||||
"@rollup/plugin-url": "8.0.1",
|
||||
"@svgr/rollup": "5.5.0",
|
||||
"@vercel/ncc": "0.36.1",
|
||||
"ajv": "6.12.6",
|
||||
"autoprefixer": "9.6.0",
|
||||
"babel-plugin-istanbul": "^5.2.0",
|
||||
"babel-plugin-react-require": "3.1.1",
|
||||
"chalk": "2.4.2",
|
||||
"chokidar": "^3.0.2",
|
||||
"es5-imcompatible-versions": "^0.1.37",
|
||||
"fast-glob": "3.3.0",
|
||||
"glob": "^7.1.4",
|
||||
"gulp-if": "2.0.2",
|
||||
"gulp-less": "^5.0.0",
|
||||
"gulp-plumber": "^1.2.1",
|
||||
"gulp": "4.0.2",
|
||||
"@types/gulp": "^4.0.13",
|
||||
"gulp-typescript": "6.0.0-alpha.1",
|
||||
"less": "4.1.3",
|
||||
"less-plugin-npm-import": "2.1.0",
|
||||
"lodash": "4.17.21",
|
||||
"pkg-up": "3.1.0",
|
||||
"rimraf": "2.6.3",
|
||||
"rollup": "3.25.1",
|
||||
"rollup-plugin-postcss": "4.0.2",
|
||||
"rollup-plugin-terser": "7.0.2",
|
||||
"rollup-plugin-typescript2": "0.34.1",
|
||||
"semver": "6.1.1",
|
||||
"signale": "1.4.0",
|
||||
"slash2": "2.0.0",
|
||||
"temp-dir": "2.0.0",
|
||||
"through2": "3.0.1",
|
||||
"ts-loader": "^9.4.3",
|
||||
"tsup": "7.1.0",
|
||||
"tsup": "7.2.0",
|
||||
"typescript": "5.1.3",
|
||||
"update-notifier": "3.0.0",
|
||||
"vinyl-fs": "3.0.3",
|
||||
"vite-plugin-lib-inject-css": "1.2.0",
|
||||
"vite-plugin-css-injected-by-js": "^3.2.1",
|
||||
"yargs-parser": "13.1.2"
|
||||
"yargs-parser": "13.1.2",
|
||||
"@types/lerna__project": "5.1.0",
|
||||
"@types/lerna__package": "5.1.0",
|
||||
"@babel/core": "7.22.10",
|
||||
"@babel/preset-env": "7.22.10",
|
||||
"@babel/plugin-transform-modules-amd": "7.22.5"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "umi-tools build"
|
||||
"build": "tsup"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/gulp-plumber": "^0.0.32",
|
||||
"umi-tools": "^0.4.0"
|
||||
},
|
||||
"gitHead": "ce588eefb0bfc50f7d5bbee575e0b5e843bf6644"
|
||||
}
|
||||
|
@ -1,272 +0,0 @@
|
||||
import { join, extname, relative } from "path";
|
||||
import { existsSync, readFileSync, statSync } from "fs";
|
||||
import vfs from "vinyl-fs";
|
||||
import signale from "signale";
|
||||
import lodash from "lodash";
|
||||
import rimraf from "rimraf";
|
||||
import through from "through2";
|
||||
import slash from "slash2";
|
||||
import * as chokidar from "chokidar";
|
||||
import * as babel from "@babel/core";
|
||||
import gulpTs from "gulp-typescript";
|
||||
import gulpLess from "gulp-less";
|
||||
import gulpPlumber from "gulp-plumber";
|
||||
import gulpIf from "gulp-if";
|
||||
import chalk from "chalk";
|
||||
import fs from 'fs-extra'
|
||||
import getBabelConfig from "./getBabelConfig";
|
||||
import { Dispose, IBundleOptions } from "./types";
|
||||
import * as ts from "typescript";
|
||||
|
||||
interface IBabelOpts {
|
||||
cwd: string;
|
||||
rootPath?: string;
|
||||
type: "esm" | "cjs";
|
||||
target?: "browser" | "node";
|
||||
log?: (string) => void;
|
||||
watch?: boolean;
|
||||
dispose?: Dispose[];
|
||||
isPlugin?: boolean;
|
||||
importLibToEs?: boolean;
|
||||
bundleOpts: IBundleOptions;
|
||||
}
|
||||
|
||||
interface ITransformOpts {
|
||||
file: {
|
||||
contents: string;
|
||||
path: string;
|
||||
};
|
||||
type: "esm" | "cjs";
|
||||
}
|
||||
|
||||
export default async function (opts: IBabelOpts) {
|
||||
const {
|
||||
cwd,
|
||||
rootPath,
|
||||
type,
|
||||
watch,
|
||||
dispose,
|
||||
importLibToEs,
|
||||
log,
|
||||
isPlugin = false,
|
||||
bundleOpts: {
|
||||
target = "browser",
|
||||
runtimeHelpers,
|
||||
extraBabelPresets = [],
|
||||
extraBabelPlugins = [],
|
||||
browserFiles = [],
|
||||
nodeFiles = [],
|
||||
nodeVersion,
|
||||
disableTypeCheck,
|
||||
cjs,
|
||||
lessInBabelMode,
|
||||
},
|
||||
} = opts;
|
||||
const srcPath = join(cwd, "src");
|
||||
const targetDir = type === "esm" ? "es" : isPlugin ? 'dist' : "lib";
|
||||
const targetPath = join(cwd, targetDir);
|
||||
|
||||
if (!isPlugin) {
|
||||
log(chalk.gray(`Clean ${targetDir} directory`));
|
||||
rimraf.sync(targetPath);
|
||||
} else {
|
||||
if (fs.existsSync(targetPath)) {
|
||||
// exclude node_modules
|
||||
const files = fs.readdirSync(targetPath, { recursive: false }) as string[];
|
||||
files.forEach((file) => {
|
||||
if (file !== 'node_modules') {
|
||||
rimraf.sync(join(targetPath, file));
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function transform(opts: ITransformOpts) {
|
||||
const { file, type } = opts;
|
||||
const { opts: babelOpts, isBrowser } = getBabelConfig({
|
||||
target,
|
||||
type,
|
||||
typescript: true,
|
||||
runtimeHelpers,
|
||||
filePath: slash(relative(cwd, file.path)),
|
||||
browserFiles,
|
||||
nodeFiles,
|
||||
nodeVersion,
|
||||
lazy: cjs && cjs.lazy,
|
||||
lessInBabelMode,
|
||||
});
|
||||
if (importLibToEs && type === "esm") {
|
||||
babelOpts.plugins.push(require.resolve("../lib/importLibToEs"));
|
||||
}
|
||||
babelOpts.presets.push(...extraBabelPresets);
|
||||
babelOpts.plugins.push(...extraBabelPlugins);
|
||||
|
||||
const relFile = slash(file.path).replace(`${cwd}/`, "");
|
||||
log(
|
||||
`Transform to ${type} for ${chalk[isBrowser ? "yellow" : "blue"](
|
||||
relFile
|
||||
)}`
|
||||
);
|
||||
|
||||
return babel.transform(file.contents, {
|
||||
...babelOpts,
|
||||
filename: file.path,
|
||||
// 不读取外部的babel.config.js配置文件,全采用babelOpts中的babel配置来构建
|
||||
configFile: false,
|
||||
}).code;
|
||||
}
|
||||
|
||||
/**
|
||||
* tsconfig.json is not valid json file
|
||||
* https://github.com/Microsoft/TypeScript/issues/20384
|
||||
*/
|
||||
function parseTsconfig(path: string) {
|
||||
const readFile = (path: string) => readFileSync(path, "utf-8");
|
||||
const result = ts.readConfigFile(path, readFile);
|
||||
if (result.error) {
|
||||
return;
|
||||
}
|
||||
const pkgTsConfig = result.config;
|
||||
if (pkgTsConfig.extends) {
|
||||
const rootTsConfigPath = slash(relative(cwd, pkgTsConfig.extends));
|
||||
const rootTsConfig = parseTsconfig(rootTsConfigPath);
|
||||
if (rootTsConfig) {
|
||||
const mergedConfig = {
|
||||
...rootTsConfig,
|
||||
...pkgTsConfig,
|
||||
compilerOptions: {
|
||||
...rootTsConfig.compilerOptions,
|
||||
...pkgTsConfig.compilerOptions,
|
||||
},
|
||||
};
|
||||
return mergedConfig;
|
||||
}
|
||||
}
|
||||
return pkgTsConfig;
|
||||
}
|
||||
|
||||
function getTsconfigCompilerOptions(path: string) {
|
||||
const config = parseTsconfig(path);
|
||||
return config ? config.compilerOptions : undefined;
|
||||
}
|
||||
|
||||
function getTSConfig() {
|
||||
const tsconfigPath = join(cwd, "tsconfig.json");
|
||||
const templateTsconfigPath = join(__dirname, "../template/tsconfig.json");
|
||||
|
||||
if (existsSync(tsconfigPath)) {
|
||||
return getTsconfigCompilerOptions(tsconfigPath) || {};
|
||||
}
|
||||
if (rootPath && existsSync(join(rootPath, "tsconfig.json"))) {
|
||||
return getTsconfigCompilerOptions(join(rootPath, "tsconfig.json")) || {};
|
||||
}
|
||||
return getTsconfigCompilerOptions(templateTsconfigPath) || {};
|
||||
}
|
||||
|
||||
function createStream(src) {
|
||||
const tsConfig = getTSConfig();
|
||||
const babelTransformRegexp = disableTypeCheck ? /\.(t|j)sx?$/ : /\.jsx?$/;
|
||||
|
||||
function isTsFile(path) {
|
||||
return /\.tsx?$/.test(path) && !path.endsWith(".d.ts");
|
||||
}
|
||||
|
||||
function isTransform(path) {
|
||||
if (isPlugin) return false
|
||||
return babelTransformRegexp.test(path) && !path.endsWith(".d.ts");
|
||||
}
|
||||
return vfs
|
||||
.src(src, {
|
||||
allowEmpty: true,
|
||||
base: srcPath,
|
||||
})
|
||||
.pipe(watch ? gulpPlumber() : through.obj())
|
||||
.pipe(
|
||||
gulpIf((f) => !disableTypeCheck && isTsFile(f.path), gulpTs(tsConfig))
|
||||
)
|
||||
.pipe(
|
||||
gulpIf(
|
||||
(f) => lessInBabelMode && /\.less$/.test(f.path),
|
||||
gulpLess(lessInBabelMode || {})
|
||||
)
|
||||
)
|
||||
.pipe(
|
||||
gulpIf(
|
||||
(f) => isTransform(f.path),
|
||||
through.obj((file, env, cb) => {
|
||||
try {
|
||||
file.contents = Buffer.from(
|
||||
transform({
|
||||
file,
|
||||
type,
|
||||
})
|
||||
);
|
||||
// .jsx -> .js
|
||||
file.path = file.path.replace(extname(file.path), ".js");
|
||||
cb(null, file);
|
||||
} catch (e) {
|
||||
signale.error(`Compiled faild: ${file.path}`);
|
||||
console.log(e);
|
||||
cb(null);
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(vfs.dest(targetPath))
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const patterns = [
|
||||
isPlugin ? join(srcPath, "**/*.{ts,tsx}") : join(srcPath, "**/*"),
|
||||
`!${join(srcPath, "**/fixtures{,/**}")}`,
|
||||
`!${join(srcPath, "**/demos{,/**}")}`,
|
||||
`!${join(srcPath, "**/__test__{,/**}")}`,
|
||||
`!${join(srcPath, "**/__tests__{,/**}")}`,
|
||||
`!${join(srcPath, "**/*.mdx")}`,
|
||||
`!${join(srcPath, "**/*.md")}`,
|
||||
`!${join(srcPath, "**/*.+(test|e2e|spec).+(js|jsx|ts|tsx)")}`,
|
||||
`!${join(srcPath, "**/tsconfig{,.*}.json")}`,
|
||||
`!${join(srcPath, ".umi{,-production,-test}{,/**}")}`,
|
||||
];
|
||||
createStream(patterns).on("end", () => {
|
||||
if (watch) {
|
||||
log(
|
||||
chalk.magenta(
|
||||
`Start watching ${slash(srcPath).replace(
|
||||
`${cwd}/`,
|
||||
""
|
||||
)} directory...`
|
||||
)
|
||||
);
|
||||
const watcher = chokidar.watch(patterns, {
|
||||
ignoreInitial: true,
|
||||
});
|
||||
|
||||
const files = [];
|
||||
function compileFiles() {
|
||||
while (files.length) {
|
||||
createStream(files.pop());
|
||||
}
|
||||
}
|
||||
|
||||
const debouncedCompileFiles = lodash.debounce(compileFiles, 1000);
|
||||
watcher.on("all", (event, fullPath) => {
|
||||
const relPath = fullPath.replace(srcPath, "");
|
||||
log(
|
||||
`[${event}] ${slash(join(srcPath, relPath)).replace(`${cwd}/`, "")}`
|
||||
);
|
||||
if (!existsSync(fullPath)) return;
|
||||
if (statSync(fullPath).isFile()) {
|
||||
if (!files.includes(fullPath)) files.push(fullPath);
|
||||
debouncedCompileFiles();
|
||||
}
|
||||
});
|
||||
process.once("SIGINT", () => {
|
||||
watcher.close();
|
||||
});
|
||||
dispose?.push(() => watcher.close());
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
import { join, basename, sep } from 'path';
|
||||
import { getPackagesSync } from '@lerna/project';
|
||||
import { existsSync, readdirSync, renameSync, statSync } from 'fs';
|
||||
import mkdirp from 'mkdirp';
|
||||
import rimraf from 'rimraf';
|
||||
import build from './build';
|
||||
|
||||
function moveEsLibToDist(cwd) {
|
||||
['es', 'lib'].forEach(dir => {
|
||||
const absDirPath = join(cwd, dir);
|
||||
const absDistPath = join(cwd, 'dist');
|
||||
if (existsSync(absDirPath)) {
|
||||
mkdirp.sync(absDistPath);
|
||||
renameSync(absDirPath, join(absDistPath, dir));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe('father build', () => {
|
||||
const rootConfigMapping = {
|
||||
'lerna-root-config-override': { cjs: 'rollup', esm: false },
|
||||
};
|
||||
|
||||
require('test-build-result')({
|
||||
root: join(__dirname, './fixtures/build'),
|
||||
build({ cwd }) {
|
||||
process.chdir(cwd);
|
||||
rimraf.sync(join(cwd, 'dist'));
|
||||
return build({ cwd, rootConfig: rootConfigMapping[basename(cwd)] }).then(() => {
|
||||
// babel
|
||||
moveEsLibToDist(cwd);
|
||||
|
||||
// lerna
|
||||
if (existsSync(join(cwd, 'lerna.json'))) {
|
||||
mkdirp.sync(join(cwd, 'dist'));
|
||||
const pkgs = getPackagesSync(cwd)
|
||||
for (let pkg of pkgs) {
|
||||
|
||||
const pkgPath = pkg.contents;
|
||||
|
||||
if (!statSync(pkgPath).isDirectory()) continue;
|
||||
moveEsLibToDist(pkgPath);
|
||||
renameSync(
|
||||
join(pkgPath, 'dist'),
|
||||
join(cwd, 'dist', pkgPath.split(sep).pop())
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
@ -1,287 +1,103 @@
|
||||
import * as assert from 'assert';
|
||||
import execa from 'execa';
|
||||
import chalk from 'chalk';
|
||||
import { existsSync, readFileSync } from 'fs';
|
||||
import { merge } from 'lodash';
|
||||
import { isAbsolute, join, sep } from 'path';
|
||||
import rimraf from 'rimraf';
|
||||
import signale from 'signale';
|
||||
import babel from './babel';
|
||||
import { buildPluginClient, buildPluginServer, deleteJsFiles } from './buildPlugin';
|
||||
import getUserConfig, { CONFIG_FILES } from './getUserConfig';
|
||||
import randomColor from './randomColor';
|
||||
import registerBabel from './registerBabel';
|
||||
import rollup from './rollup';
|
||||
import { Dispose, IBundleOptions, IBundleTypeOutput, ICjs, IEsm, IOpts } from './types';
|
||||
import { getExistFiles, getLernaPackages } from './utils';
|
||||
import path from 'path';
|
||||
import {
|
||||
PACKAGES_PATH,
|
||||
getPluginPackages,
|
||||
CORE_CLIENT,
|
||||
CORE_APP,
|
||||
getCjsPackages,
|
||||
getPresetsPackages,
|
||||
ROOT_PATH,
|
||||
} from './constant';
|
||||
import { buildClient } from './buildClient';
|
||||
import { buildCjs } from './buildCjs';
|
||||
import { buildPlugin } from './buildPlugin';
|
||||
import { buildDeclaration } from './buildDeclaration';
|
||||
import { PkgLog, getPkgLog, toUnixPath, getPackageJson } from './utils';
|
||||
import { getPackages } from './utils/getPackages';
|
||||
import { Package } from '@lerna/package';
|
||||
|
||||
export function getBundleOpts(opts: IOpts): IBundleOptions[] {
|
||||
const { cwd, buildArgs = {}, rootConfig = {} } = opts;
|
||||
const entry = getExistFiles({
|
||||
export async function build(pkgs: string[]) {
|
||||
const packages = getPackages(pkgs);
|
||||
const pluginPackages = getPluginPackages(packages);
|
||||
const cjsPackages = getCjsPackages(packages);
|
||||
const presetsPackages = getPresetsPackages(packages);
|
||||
|
||||
// core/*
|
||||
await buildPackages(cjsPackages, 'lib', buildCjs);
|
||||
const clientCore = packages.find((item) => item.location === CORE_CLIENT);
|
||||
if (clientCore) {
|
||||
await buildPackage(clientCore, 'es', buildClient);
|
||||
}
|
||||
|
||||
// plugins/*、samples/*
|
||||
await buildPackages(pluginPackages, 'dist', buildPlugin);
|
||||
|
||||
// presets/*
|
||||
await buildPackages(presetsPackages, 'lib', buildCjs);
|
||||
|
||||
// core/app
|
||||
const appClient = packages.find((item) => item.location === CORE_APP);
|
||||
if (appClient) {
|
||||
await runScript(['umi', 'build'], ROOT_PATH, {
|
||||
APP_ROOT: path.join(CORE_APP, 'client'),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function buildPackages(
|
||||
packages: Package[],
|
||||
targetDir: string,
|
||||
doBuildPackage: (cwd: string, sourcemap: boolean, log?: PkgLog) => Promise<any>,
|
||||
) {
|
||||
for await (const pkg of packages) {
|
||||
await buildPackage(pkg, targetDir, doBuildPackage);
|
||||
}
|
||||
}
|
||||
|
||||
export async function buildPackage(
|
||||
pkg: Package,
|
||||
targetDir: string,
|
||||
doBuildPackage: (cwd: string, sourcemap: boolean, log?: PkgLog) => Promise<any>,
|
||||
) {
|
||||
const sourcemap = process.argv.includes('--sourcemap');
|
||||
const noDeclaration = process.argv.includes('--no-dts');
|
||||
const log = getPkgLog(pkg.name);
|
||||
const packageJson = getPackageJson(pkg.location);
|
||||
log(`${chalk.bold(toUnixPath(pkg.location.replace(PACKAGES_PATH, '').slice(1)))} build start`);
|
||||
|
||||
// prebuild
|
||||
if (packageJson?.scripts?.prebuild) {
|
||||
log('prebuild');
|
||||
await runScript(['prebuild'], pkg.location);
|
||||
await packageJson.prebuild(pkg.location);
|
||||
}
|
||||
|
||||
// build source
|
||||
await doBuildPackage(pkg.location, sourcemap, log);
|
||||
|
||||
// build declaration
|
||||
if (!noDeclaration) {
|
||||
log('build declaration');
|
||||
await buildDeclaration(pkg.location, targetDir);
|
||||
}
|
||||
|
||||
// postbuild
|
||||
if (packageJson?.scripts?.postbuild) {
|
||||
log('postbuild');
|
||||
await runScript(['postbuild'], pkg.location);
|
||||
}
|
||||
}
|
||||
|
||||
function runScript(args: string[], cwd: string, envs: Record<string, string> = {}) {
|
||||
return execa('yarn', args, {
|
||||
cwd,
|
||||
files: [
|
||||
'src/index.tsx',
|
||||
'src/index.ts',
|
||||
'src/index.jsx',
|
||||
'src/index.js',
|
||||
'src/server/index.ts',
|
||||
'src/server/index.js',
|
||||
'src/client/index.js',
|
||||
'src/client/index.ts',
|
||||
'src/client/index.tsx',
|
||||
],
|
||||
onlyOne: false,
|
||||
returnRelative: true,
|
||||
});
|
||||
const userConfig = getUserConfig({ cwd, customPath: buildArgs.config });
|
||||
const userConfigs = Array.isArray(userConfig) ? userConfig : [userConfig];
|
||||
return (userConfigs as any).map((userConfig) => {
|
||||
const bundleOpts = merge(
|
||||
{
|
||||
entry,
|
||||
},
|
||||
rootConfig,
|
||||
userConfig,
|
||||
buildArgs,
|
||||
);
|
||||
|
||||
// Support config esm: 'rollup' and cjs: 'rollup'
|
||||
if (typeof bundleOpts.esm === 'string') {
|
||||
bundleOpts.esm = { type: bundleOpts.esm };
|
||||
}
|
||||
if (typeof bundleOpts.cjs === 'string') {
|
||||
bundleOpts.cjs = { type: bundleOpts.cjs };
|
||||
}
|
||||
|
||||
return bundleOpts;
|
||||
stdio: 'inherit',
|
||||
env: {
|
||||
...process.env,
|
||||
...envs,
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function validateBundleOpts(bundleOpts: IBundleOptions, { cwd, rootPath }) {
|
||||
if (bundleOpts.runtimeHelpers) {
|
||||
const pkgPath = join(cwd, 'package.json');
|
||||
assert.ok(existsSync(pkgPath), `@babel/runtime dependency is required to use runtimeHelpers`);
|
||||
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
||||
assert.ok(
|
||||
(pkg.dependencies || {})['@babel/runtime'],
|
||||
`@babel/runtime dependency is required to use runtimeHelpers`,
|
||||
);
|
||||
}
|
||||
if (bundleOpts.cjs && (bundleOpts.cjs as ICjs).lazy && (bundleOpts.cjs as ICjs).type === 'rollup') {
|
||||
throw new Error(
|
||||
`
|
||||
cjs.lazy don't support rollup.
|
||||
`.trim(),
|
||||
);
|
||||
}
|
||||
if (!bundleOpts.esm && !bundleOpts.cjs && !bundleOpts.umd) {
|
||||
throw new Error(
|
||||
`
|
||||
None format of ${chalk.cyan(
|
||||
'cjs | esm | umd',
|
||||
)} is configured, checkout https://github.com/umijs/father for usage details.
|
||||
`.trim(),
|
||||
);
|
||||
}
|
||||
if (bundleOpts.entry) {
|
||||
const tsConfigPath = join(cwd, 'tsconfig.json');
|
||||
const tsConfig = existsSync(tsConfigPath) || (rootPath && existsSync(join(rootPath, 'tsconfig.json')));
|
||||
if (
|
||||
!tsConfig &&
|
||||
((Array.isArray(bundleOpts.entry) && bundleOpts.entry.some(isTypescriptFile)) ||
|
||||
(!Array.isArray(bundleOpts.entry) && isTypescriptFile(bundleOpts.entry)))
|
||||
) {
|
||||
signale.info(`Project using ${chalk.cyan('typescript')} but tsconfig.json not exists. Use default config.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isTypescriptFile(filePath) {
|
||||
return filePath.endsWith('.ts') || filePath.endsWith('.tsx');
|
||||
}
|
||||
|
||||
function isPluginPackage(name: string) {
|
||||
const prefixes = (process.env.PLUGIN_PACKAGE_PREFIX || '').split(',');
|
||||
for (const prefix of prefixes) {
|
||||
if (prefix.includes('preset')) {
|
||||
continue;
|
||||
}
|
||||
if (name.startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
interface IExtraBuildOpts {
|
||||
pkg?: string | { name?: string };
|
||||
}
|
||||
|
||||
export async function build(opts: IOpts, extraOpts: IExtraBuildOpts = {}) {
|
||||
const { cwd, rootPath, watch, buildArgs = {}, clean = true } = opts;
|
||||
const { pkg } = extraOpts;
|
||||
|
||||
const dispose: Dispose[] = [];
|
||||
|
||||
const customConfigPath =
|
||||
buildArgs.config && (isAbsolute(buildArgs.config) ? buildArgs.config : join(process.cwd(), buildArgs.config));
|
||||
|
||||
// register babel for config files
|
||||
registerBabel({
|
||||
cwd,
|
||||
only: customConfigPath ? CONFIG_FILES.concat(customConfigPath) : CONFIG_FILES,
|
||||
});
|
||||
|
||||
const pkgName = (typeof pkg === 'string' ? pkg : pkg?.name) || 'unknown';
|
||||
|
||||
function log(msg, ...args) {
|
||||
console.log(`${pkg ? `${randomColor(`${pkgName}`)}: ` : ''}${msg}`, ...args);
|
||||
}
|
||||
|
||||
// Get user config
|
||||
const bundleOptsArray = getBundleOpts(opts);
|
||||
const isPlugin = isPluginPackage(pkgName);
|
||||
|
||||
// Clean dist
|
||||
if (clean && !isPlugin) {
|
||||
log(chalk.gray(`Clean dist directory`));
|
||||
rimraf.sync(join(cwd, 'dist'));
|
||||
}
|
||||
|
||||
for (const bundleOpts of bundleOptsArray) {
|
||||
validateBundleOpts(bundleOpts, { cwd, rootPath });
|
||||
|
||||
// Build umd
|
||||
if (bundleOpts.umd) {
|
||||
log(`Build umd`);
|
||||
await rollup({
|
||||
cwd,
|
||||
rootPath,
|
||||
log,
|
||||
type: 'umd',
|
||||
entry: bundleOpts.entry,
|
||||
watch,
|
||||
dispose,
|
||||
bundleOpts,
|
||||
});
|
||||
}
|
||||
|
||||
// Build cjs
|
||||
if (bundleOpts.cjs) {
|
||||
const cjs = bundleOpts.cjs as IBundleTypeOutput;
|
||||
log(`Build ${isPlugin ? 'd.ts' : 'cjs'} with ${cjs.type}`);
|
||||
if (cjs.type === 'babel') {
|
||||
await babel({ cwd, rootPath, watch, dispose, isPlugin, type: 'cjs', log, bundleOpts });
|
||||
if (isPlugin) {
|
||||
log(cwd);
|
||||
deleteJsFiles(cwd, log);
|
||||
await buildPluginServer(cwd, log);
|
||||
await buildPluginClient(cwd, log);
|
||||
const buildFile = join(cwd, 'build.js');
|
||||
if (existsSync(buildFile)) {
|
||||
log('build others');
|
||||
try {
|
||||
await require(buildFile).run(log);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await rollup({
|
||||
cwd,
|
||||
rootPath,
|
||||
log,
|
||||
type: 'cjs',
|
||||
entry: bundleOpts.entry,
|
||||
watch,
|
||||
dispose,
|
||||
bundleOpts,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Build esm
|
||||
if (bundleOpts.esm) {
|
||||
const esm = bundleOpts.esm as IEsm;
|
||||
log(`Build esm with ${esm.type}`);
|
||||
const importLibToEs = esm && esm.importLibToEs;
|
||||
if (esm && esm.type === 'babel') {
|
||||
await babel({ cwd, rootPath, watch, dispose, type: 'esm', importLibToEs, log, bundleOpts });
|
||||
} else {
|
||||
await rollup({
|
||||
cwd,
|
||||
rootPath,
|
||||
log,
|
||||
type: 'esm',
|
||||
entry: bundleOpts.entry,
|
||||
importLibToEs,
|
||||
watch,
|
||||
dispose,
|
||||
bundleOpts,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dispose;
|
||||
}
|
||||
|
||||
function getPkgRelativePath(cwd, pkg) {
|
||||
const basePath = cwd.split(sep).join('/') + '/packages/';
|
||||
const dir = pkg.contents.split(sep).join('/');
|
||||
return dir.substring(basePath.length);
|
||||
}
|
||||
|
||||
export async function buildForLerna(opts: IOpts) {
|
||||
const { cwd, rootConfig = {}, buildArgs = {}, packages = [] } = opts;
|
||||
|
||||
// register babel for config files
|
||||
registerBabel({
|
||||
cwd,
|
||||
only: CONFIG_FILES,
|
||||
});
|
||||
|
||||
const userConfig = merge(getUserConfig({ cwd }), rootConfig, buildArgs);
|
||||
|
||||
let pkgs = await getLernaPackages(cwd, userConfig.pkgFilter);
|
||||
// support define pkgs in lerna
|
||||
if (userConfig.pkgs) {
|
||||
pkgs = pkgs.filter((pkg) => userConfig.pkgs.includes(getPkgRelativePath(cwd, pkg)));
|
||||
}
|
||||
const dispose: Dispose[] = [];
|
||||
for (const pkg of pkgs) {
|
||||
const pkgName = getPkgRelativePath(cwd, pkg);
|
||||
if (userConfig.excludePkgs && userConfig.excludePkgs.includes(pkgName)) {
|
||||
continue;
|
||||
}
|
||||
if (packages.length && !packages.includes(pkgName)) continue;
|
||||
// build error when .DS_Store includes in packages root
|
||||
const pkgPath = pkg.contents;
|
||||
assert.ok(existsSync(join(pkgPath, 'package.json')), `package.json not found in packages/${pkg}`);
|
||||
process.chdir(pkgPath);
|
||||
dispose.push(
|
||||
...(await build(
|
||||
{
|
||||
// eslint-disable-line
|
||||
...opts,
|
||||
buildArgs: opts.buildArgs,
|
||||
rootConfig: userConfig,
|
||||
cwd: pkgPath,
|
||||
rootPath: cwd,
|
||||
},
|
||||
{
|
||||
pkg,
|
||||
},
|
||||
)),
|
||||
);
|
||||
}
|
||||
return dispose;
|
||||
}
|
||||
|
||||
export default async function (opts: IOpts) {
|
||||
const useLerna = existsSync(join(opts.cwd, 'lerna.json'));
|
||||
const isLerna = useLerna && process.env.LERNA !== 'none';
|
||||
|
||||
const dispose = isLerna ? await buildForLerna(opts) : await build(opts);
|
||||
return () => dispose.forEach((e) => e());
|
||||
}
|
||||
|
36
packages/core/build/src/buildCjs.ts
Normal file
36
packages/core/build/src/buildCjs.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { build } from 'tsup';
|
||||
import fg from 'fast-glob';
|
||||
import path from 'path';
|
||||
import chalk from 'chalk';
|
||||
import { globExcludeFiles, EsbuildSupportExts } from './constant';
|
||||
import { PkgLog } from './utils';
|
||||
|
||||
export function buildCjs(cwd: string, sourcemap: boolean = false, log: PkgLog) {
|
||||
log('build cjs');
|
||||
|
||||
const entry = fg.globSync(['src/**', ...globExcludeFiles], { cwd, absolute: true });
|
||||
const outDir = path.join(cwd, 'lib');
|
||||
const otherExts = Array.from(new Set(entry.map((item) => path.extname(item)).filter((item) => !EsbuildSupportExts.includes(item))));
|
||||
if (otherExts.length) {
|
||||
log('%s will not be processed, only be copied to the lib directory.', chalk.yellow(otherExts.join(',')));
|
||||
}
|
||||
|
||||
return build({
|
||||
entry,
|
||||
splitting: false,
|
||||
clean: true,
|
||||
bundle: false,
|
||||
silent: true,
|
||||
sourcemap,
|
||||
treeshake: false,
|
||||
target: 'node16',
|
||||
keepNames: true,
|
||||
outDir,
|
||||
loader: {
|
||||
...otherExts.reduce((prev, cur) => ({ ...prev, [cur]: 'copy' }), {}),
|
||||
'.json': 'copy',
|
||||
},
|
||||
format: 'cjs',
|
||||
skipNodeModulesBundle: true,
|
||||
});
|
||||
}
|
71
packages/core/build/src/buildClient.ts
Normal file
71
packages/core/build/src/buildClient.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import path from 'path';
|
||||
import fg from 'fast-glob';
|
||||
import { build as viteBuild } from 'vite';
|
||||
import { build as tsupBuild } from 'tsup';
|
||||
import { libInjectCss } from 'vite-plugin-lib-inject-css';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { PkgLog } from './utils';
|
||||
import { globExcludeFiles } from './constant';
|
||||
|
||||
export async function buildClient(cwd: string, sourcemap: boolean = false, log: PkgLog) {
|
||||
log('build client');
|
||||
|
||||
await Promise.all([buildLib(cwd, sourcemap, 'cjs'), buildLib(cwd, sourcemap, 'es')]);
|
||||
await buildLocale(cwd);
|
||||
}
|
||||
|
||||
export function buildLib(cwd: string, sourcemap: boolean, format: 'cjs' | 'es') {
|
||||
const outDir = path.resolve(cwd, format === 'cjs' ? 'lib' : 'es');
|
||||
const entry = path.join(cwd, 'src/index.ts').replaceAll(/\\/g, '/');
|
||||
const cwdWin = cwd.replaceAll(/\\/g, '/');
|
||||
const cwdUnix = cwd.replaceAll(/\//g, '\\');
|
||||
|
||||
return viteBuild({
|
||||
mode: 'production',
|
||||
define: {
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
},
|
||||
build: {
|
||||
minify: false,
|
||||
outDir,
|
||||
cssCodeSplit: true,
|
||||
emptyOutDir: true,
|
||||
sourcemap,
|
||||
lib: {
|
||||
entry,
|
||||
formats: [format],
|
||||
fileName: 'index',
|
||||
},
|
||||
target: ['es2015', 'edge88', 'firefox78', 'chrome87', 'safari14'],
|
||||
rollupOptions: {
|
||||
cache: true,
|
||||
treeshake: true,
|
||||
external(id) {
|
||||
if (id.startsWith('.') || id.startsWith(cwdUnix) || id.startsWith(cwdWin)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [react(), libInjectCss()],
|
||||
});
|
||||
}
|
||||
|
||||
export function buildLocale(cwd: string) {
|
||||
const entry = fg.globSync(['src/locale/**', ...globExcludeFiles], { cwd, absolute: true });
|
||||
const outDir = path.resolve(cwd, 'lib', 'locale');
|
||||
return tsupBuild({
|
||||
entry,
|
||||
splitting: false,
|
||||
clean: false,
|
||||
bundle: false,
|
||||
silent: true,
|
||||
treeshake: false,
|
||||
target: 'node16',
|
||||
keepNames: true,
|
||||
outDir,
|
||||
format: 'cjs',
|
||||
skipNodeModulesBundle: true,
|
||||
});
|
||||
}
|
33
packages/core/build/src/buildDeclaration.ts
Normal file
33
packages/core/build/src/buildDeclaration.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import gulp from 'gulp';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import gulpTs from 'gulp-typescript';
|
||||
import { ROOT_PATH } from './constant';
|
||||
|
||||
export const buildDeclaration = (cwd: string, targetDir: string) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const srcPath = path.join(cwd, 'src');
|
||||
const targetPath = path.join(cwd, targetDir);
|
||||
|
||||
const tsConfig = gulpTs.createProject(path.join(ROOT_PATH, 'tsconfig.json'));
|
||||
delete tsConfig.config.compilerOptions.paths;
|
||||
const patterns = [
|
||||
path.join(srcPath, '**/*.{ts,tsx}'),
|
||||
`!${path.join(srcPath, '**/fixtures{,/**}')}`,
|
||||
`!${path.join(srcPath, '**/demos{,/**}')}`,
|
||||
`!${path.join(srcPath, '**/__test__{,/**}')}`,
|
||||
`!${path.join(srcPath, '**/__tests__{,/**}')}`,
|
||||
`!${path.join(srcPath, '**/*.mdx')}`,
|
||||
`!${path.join(srcPath, '**/*.md')}`,
|
||||
`!${path.join(srcPath, '**/*.+(test|e2e|spec).+(js|jsx|ts|tsx)')}`,
|
||||
`!${path.join(srcPath, '**/tsconfig{,.*}.json')}`,
|
||||
`!${path.join(srcPath, '.umi{,-production,-test}{,/**}')}`,
|
||||
];
|
||||
gulp
|
||||
.src(patterns, { base: srcPath, allowEmpty: true })
|
||||
.pipe(gulpTs(tsConfig.config.compilerOptions))
|
||||
.dts.pipe(gulp.dest(targetPath))
|
||||
.on('end', resolve)
|
||||
.on('error', reject);
|
||||
});
|
||||
};
|
@ -1,26 +1,30 @@
|
||||
import ncc from '@vercel/ncc';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import chalk from 'chalk';
|
||||
import fg from 'fast-glob';
|
||||
import fs from 'fs-extra';
|
||||
import chalk from 'chalk';
|
||||
import ncc from '@vercel/ncc';
|
||||
import path from 'path';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { build as tsupBuild } from 'tsup';
|
||||
import { build as viteBuild } from 'vite';
|
||||
import fg from 'fast-glob';
|
||||
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
|
||||
import { transformAsync } from '@babel/core';
|
||||
|
||||
import {
|
||||
buildCheck,
|
||||
formatFileSize,
|
||||
checkFileSize,
|
||||
checkRequire,
|
||||
getExcludePackages,
|
||||
getFileSize,
|
||||
getIncludePackages,
|
||||
getPackageJson,
|
||||
getPackagesFromFiles,
|
||||
getSourcePackages,
|
||||
} from './utils/buildPluginUtils';
|
||||
import { getDepsConfig } from './utils/getDepsConfig';
|
||||
import { EsbuildSupportExts, globExcludeFiles } from './constant';
|
||||
import { PkgLog, getPackageJson } from './utils';
|
||||
|
||||
const serverGlobalFiles: string[] = ['src/**', '!src/**/__tests__', '!src/client/**'];
|
||||
|
||||
const clientGlobalFiles: string[] = ['src/client/**', '!src/**/__tests__'];
|
||||
const serverGlobalFiles: string[] = ['src/**', '!src/client/**', ...globExcludeFiles];
|
||||
const clientGlobalFiles: string[] = ['src/**', '!src/server/**', ...globExcludeFiles];
|
||||
const dynamicImportRegexp = /import\((["'])(.*?)\1\)/g;
|
||||
|
||||
const external = [
|
||||
// nocobase
|
||||
@ -116,17 +120,14 @@ const external = [
|
||||
'ahooks',
|
||||
'lodash',
|
||||
'china-division',
|
||||
'cronstrue',
|
||||
];
|
||||
const pluginPrefix = (
|
||||
process.env.PLUGIN_PACKAGE_PREFIX || '@nocobase/plugin-,@nocobase/preset-,@nocobase/plugin-pro-'
|
||||
).split(',');
|
||||
|
||||
type Log = (msg: string, ...args: any) => void;
|
||||
|
||||
const target_dir = 'dist';
|
||||
|
||||
export function deleteJsFiles(cwd: string, log: Log) {
|
||||
export function deleteJsFiles(cwd: string, log: PkgLog) {
|
||||
log('delete babel js files');
|
||||
const jsFiles = fg.globSync(['**/*', '!**/*.d.ts', '!node_modules'], {
|
||||
cwd: path.join(cwd, target_dir),
|
||||
@ -137,23 +138,24 @@ export function deleteJsFiles(cwd: string, log: Log) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function buildServerDeps(cwd: string, serverFiles: string[], log: Log) {
|
||||
log('build server dependencies');
|
||||
export async function buildServerDeps(cwd: string, serverFiles: string[], log: PkgLog) {
|
||||
log('build plugin server dependencies');
|
||||
const outDir = path.join(cwd, target_dir, 'node_modules');
|
||||
const sourcePackages = getSourcePackages(serverFiles);
|
||||
const serverFileSource = serverFiles.map((item) => fs.readFileSync(item, 'utf-8'));
|
||||
const sourcePackages = getSourcePackages(serverFileSource);
|
||||
const includePackages = getIncludePackages(sourcePackages, external, pluginPrefix);
|
||||
const excludePackages = getExcludePackages(sourcePackages, external, pluginPrefix);
|
||||
|
||||
let tips = [];
|
||||
if (includePackages.length) {
|
||||
tips.push(
|
||||
`These packages ${chalk.yellow(includePackages.join(', '))} will be ${chalk.bold(
|
||||
`These packages ${chalk.yellow(includePackages.join(', '))} will be ${chalk.italic(
|
||||
'bundled',
|
||||
)} to dist/node_modules.`,
|
||||
);
|
||||
}
|
||||
if (excludePackages.length) {
|
||||
tips.push(`These packages ${chalk.yellow(excludePackages.join(', '))} will be ${chalk.bold('exclude')}.`);
|
||||
tips.push(`These packages ${chalk.yellow(excludePackages.join(', '))} will be ${chalk.italic('exclude')}.`);
|
||||
}
|
||||
tips.push(`For more information, please refer to: ${chalk.blue('https://docs.nocobase.com/development/deps')}.`);
|
||||
log(tips.join(' '));
|
||||
@ -228,11 +230,15 @@ export async function buildServerDeps(cwd: string, serverFiles: string[], log: L
|
||||
}
|
||||
}
|
||||
|
||||
export async function buildPluginServer(cwd: string, log: Log) {
|
||||
log('build server source');
|
||||
export async function buildPluginServer(cwd: string, sourcemap: boolean, log: PkgLog) {
|
||||
log('build plugin server source');
|
||||
const packageJson = getPackageJson(cwd);
|
||||
const serverFiles = fg.globSync(serverGlobalFiles, { cwd, absolute: true });
|
||||
buildCheck({ cwd, packageJson, entry: 'server', files: serverFiles, log });
|
||||
const otherExts = Array.from(new Set(serverFiles.map((item) => path.extname(item)).filter((item) => !EsbuildSupportExts.includes(item))));
|
||||
if (otherExts.length) {
|
||||
log('%s will not be processed, only be copied to the dist directory.', chalk.yellow(otherExts.join(',')));
|
||||
}
|
||||
|
||||
await tsupBuild({
|
||||
entry: serverFiles,
|
||||
@ -240,26 +246,73 @@ export async function buildPluginServer(cwd: string, log: Log) {
|
||||
clean: false,
|
||||
bundle: false,
|
||||
silent: true,
|
||||
treeshake: true,
|
||||
treeshake: false,
|
||||
target: 'node16',
|
||||
sourcemap,
|
||||
outDir: path.join(cwd, target_dir),
|
||||
format: 'cjs',
|
||||
skipNodeModulesBundle: true,
|
||||
loader: {
|
||||
...otherExts.reduce((prev, cur) => ({ ...prev, [cur]: 'copy' }), {}),
|
||||
'.json': 'copy',
|
||||
},
|
||||
});
|
||||
|
||||
await buildServerDeps(cwd, serverFiles, log);
|
||||
}
|
||||
|
||||
export function buildPluginClient(cwd: string, log: Log) {
|
||||
log('build client');
|
||||
export function transformClientFilesToAmd(outDir: string, outputFileName: string, packageName: string, log: PkgLog) {
|
||||
const files = fs.readdirSync(outDir);
|
||||
|
||||
return Promise.all(files.map(async file => {
|
||||
const filePath = path.join(outDir, file);
|
||||
|
||||
// 只编译 JavaScript 文件
|
||||
if (path.extname(filePath) === '.mjs' || path.extname(filePath) === '.js') {
|
||||
let fileContent = fs.readFileSync(filePath, 'utf-8');
|
||||
|
||||
// import('./dayjs.mjs') => import(window.staticBaseUrl + '/@nocobase/plugin-acl/dayjs.mjs?noExt')
|
||||
if (file === outputFileName) {
|
||||
fileContent = fileContent.replace(dynamicImportRegexp, (match, _1, dynamicImportPath) => {
|
||||
let absolutePath = path.join(outDir, dynamicImportPath).replace(outDir, '');
|
||||
if (absolutePath.startsWith(path.sep)) {
|
||||
absolutePath = absolutePath.slice(1);
|
||||
}
|
||||
return `import(window.staticBaseUrl + '/${packageName}/${absolutePath}?noExt')`;
|
||||
})
|
||||
}
|
||||
|
||||
const { code } = await transformAsync(fileContent, {
|
||||
presets: [['@babel/preset-env', {
|
||||
modules: 'amd',
|
||||
targets: {
|
||||
'edge': 88,
|
||||
'firefox': 78,
|
||||
'chrome': 87,
|
||||
'safari': 14,
|
||||
}
|
||||
}]],
|
||||
plugins: ['@babel/plugin-transform-modules-amd'],
|
||||
});
|
||||
fs.writeFileSync(filePath, code, 'utf-8');
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
export async function buildPluginClient(cwd: string, sourcemap: boolean, log: PkgLog) {
|
||||
log('build plugin client');
|
||||
const packageJson = getPackageJson(cwd);
|
||||
const clientFiles = fg.globSync(clientGlobalFiles, { cwd, absolute: true });
|
||||
const sourcePackages = getSourcePackages(clientFiles);
|
||||
const clientFileSource = clientFiles.map((item) => fs.readFileSync(item, 'utf-8'));
|
||||
const sourcePackages = getPackagesFromFiles(clientFileSource);
|
||||
const excludePackages = getExcludePackages(sourcePackages, external, pluginPrefix);
|
||||
|
||||
checkRequire(clientFiles, log);
|
||||
buildCheck({ cwd, packageJson, entry: 'client', files: clientFiles, log });
|
||||
|
||||
const hasDynamicImport = false;
|
||||
// const hasDynamicImport = clientFileSource.some((source) => {
|
||||
// return source.match(dynamicImportRegexp);
|
||||
// });
|
||||
const outDir = path.join(cwd, target_dir, 'client');
|
||||
|
||||
const globals = excludePackages.reduce<Record<string, string>>((prev, curr) => {
|
||||
@ -270,48 +323,63 @@ export function buildPluginClient(cwd: string, log: Log) {
|
||||
return prev;
|
||||
}, {});
|
||||
|
||||
const entry = fg.globSync('src/client/index.{ts,tsx,js,jsx}', { cwd });
|
||||
const entry = fg.globSync('src/client/index.{ts,tsx,js,jsx}', { absolute: true, cwd });
|
||||
const outputFileName = 'index.js';
|
||||
return viteBuild({
|
||||
await viteBuild({
|
||||
mode: 'production',
|
||||
define: {
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
},
|
||||
logLevel: 'warn',
|
||||
build: {
|
||||
minify: false,
|
||||
minify: true,
|
||||
outDir,
|
||||
cssCodeSplit: false,
|
||||
emptyOutDir: false,
|
||||
emptyOutDir: true,
|
||||
sourcemap,
|
||||
lib: {
|
||||
entry,
|
||||
formats: ['umd'],
|
||||
formats: [hasDynamicImport ? 'es' : 'umd'],
|
||||
name: packageJson.name,
|
||||
fileName: () => outputFileName,
|
||||
},
|
||||
target: ['es2015', 'edge88', 'firefox78', 'chrome87', 'safari14'],
|
||||
rollupOptions: {
|
||||
cache: true,
|
||||
external: Object.keys(globals),
|
||||
external: [...Object.keys(globals), 'react', 'react/jsx-runtime'],
|
||||
output: {
|
||||
exports: 'named',
|
||||
globals,
|
||||
globals: {
|
||||
react: 'React',
|
||||
'react/jsx-runtime': 'jsxRuntime',
|
||||
...globals,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
react(),
|
||||
cssInjectedByJsPlugin({ styleId: packageJson.name }),
|
||||
{
|
||||
name: 'check-file-size',
|
||||
closeBundle() {
|
||||
const file = path.join(outDir, outputFileName);
|
||||
if (!fs.existsSync(file)) return;
|
||||
const fileSize = getFileSize(path.join(outDir, outputFileName));
|
||||
if (fileSize > 1024 * 1024) {
|
||||
log('The bundle file size exceeds 1MB %s. ', chalk.red(formatFileSize(fileSize)));
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
checkFileSize(outDir, log);
|
||||
|
||||
// if (hasDynamicImport) {
|
||||
// await transformClientFilesToAmd(outDir, outputFileName, packageJson.name, log);
|
||||
// }
|
||||
}
|
||||
|
||||
export async function buildPlugin(cwd: string, sourcemap: boolean, log: PkgLog) {
|
||||
await buildPluginClient(cwd, sourcemap, log);
|
||||
await buildPluginServer(cwd, sourcemap, log);
|
||||
const buildFile = path.join(cwd, 'build.js');
|
||||
if (fs.existsSync(buildFile)) {
|
||||
log('build others');
|
||||
try {
|
||||
await require(buildFile).run(log);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
46
packages/core/build/src/constant.ts
Normal file
46
packages/core/build/src/constant.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import path from 'path';
|
||||
import { Package } from '@lerna/package';
|
||||
|
||||
export const globExcludeFiles = [
|
||||
'!src/**/__tests__',
|
||||
'!src/**/__test__',
|
||||
'!src/**/demos',
|
||||
'!src/**/fixtures',
|
||||
'!src/**/*.mdx',
|
||||
'!src/**/*.md',
|
||||
'!src/**/*.+(test|e2e|spec).+(js|jsx|ts|tsx)',
|
||||
];
|
||||
export const EsbuildSupportExts = [
|
||||
'.ts',
|
||||
'.tsx',
|
||||
'.js',
|
||||
'.jsx',
|
||||
'.json',
|
||||
'.css',
|
||||
'.less',
|
||||
'.sass',
|
||||
'.scss',
|
||||
'.styl',
|
||||
'.txt',
|
||||
'.data',
|
||||
];
|
||||
export const ROOT_PATH = path.join(__dirname, '../../../../');
|
||||
export const PACKAGES_PATH = path.join(ROOT_PATH, 'packages');
|
||||
export const PLUGINS_DIR = [path.join(PACKAGES_PATH, 'plugins'), path.join(PACKAGES_PATH, 'samples')];
|
||||
export const PRESETS_DIR = path.join(PACKAGES_PATH, 'presets');
|
||||
export const getPluginPackages = (packages: Package[]) =>
|
||||
packages.filter((item) => PLUGINS_DIR.some((pluginDir) => item.location.startsWith(pluginDir)));
|
||||
export const getPresetsPackages = (packages: Package[]) =>
|
||||
packages.filter((item) => item.location.startsWith(PRESETS_DIR));
|
||||
export const CORE_APP = path.join(PACKAGES_PATH, 'core/app');
|
||||
export const CORE_CLIENT = path.join(PACKAGES_PATH, 'core/client');
|
||||
export const CJS_EXCLUDE_PACKAGES = [
|
||||
path.join(PACKAGES_PATH, 'core/build'),
|
||||
path.join(PACKAGES_PATH, 'core/cli'),
|
||||
CORE_CLIENT,
|
||||
];
|
||||
export const getCjsPackages = (packages: Package[]) =>
|
||||
packages
|
||||
.filter((item) => !PLUGINS_DIR.some((dir) => item.location.startsWith(dir)))
|
||||
.filter((item) => !item.location.startsWith(PRESETS_DIR))
|
||||
.filter((item) => !CJS_EXCLUDE_PACKAGES.includes(item.location));
|
@ -1,33 +0,0 @@
|
||||
// 参考:
|
||||
// https://github.com/umijs/umi/blob/2.x/packages/af-webpack/src/getWebpackConfig/es5ImcompatibleVersions.js
|
||||
import { dirname } from 'path';
|
||||
import pkgUp from 'pkg-up';
|
||||
import { satisfies } from 'semver';
|
||||
|
||||
const pkgPathCache = {};
|
||||
const pkgCache = {};
|
||||
const {
|
||||
config: { 'es5-imcompatible-versions': config },
|
||||
} = require('es5-imcompatible-versions/package.json');
|
||||
|
||||
export function getPkgPath(filePath: string) {
|
||||
const dir = dirname(filePath);
|
||||
if (dir in pkgPathCache) return pkgPathCache[dir];
|
||||
pkgPathCache[dir] = pkgUp.sync({ cwd: filePath });
|
||||
return pkgPathCache[dir];
|
||||
}
|
||||
|
||||
export function shouldTransform(pkgPath: string) {
|
||||
if (pkgPath in pkgCache) return pkgCache[pkgPath];
|
||||
const { name, version } = require(pkgPath);
|
||||
pkgCache[pkgPath] = isMatch(name, version);
|
||||
return pkgCache[pkgPath];
|
||||
}
|
||||
|
||||
function isMatch(name, version) {
|
||||
if (config[name]) {
|
||||
return Object.keys(config[name]).some((sv) => satisfies(version, sv));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
|
||||
export default {
|
||||
esm: 'babel',
|
||||
target: 'node',
|
||||
browserFiles: [
|
||||
'src/browser.js',
|
||||
],
|
||||
}
|
@ -1 +0,0 @@
|
||||
var b = 'foo';
|
@ -1 +0,0 @@
|
||||
const a = 'foo';
|
@ -1,2 +0,0 @@
|
||||
|
||||
const b = 'foo';
|
@ -1,2 +0,0 @@
|
||||
|
||||
const a = 'foo';
|
@ -1,8 +0,0 @@
|
||||
|
||||
export default {
|
||||
target: 'node',
|
||||
cjs: { type: 'babel', lazy: true },
|
||||
browserFiles: [
|
||||
'src/foo.js',
|
||||
],
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
import bar from 'bar';
|
||||
|
||||
bar();
|
@ -1,3 +0,0 @@
|
||||
import bar from 'bar';
|
||||
|
||||
bar();
|
@ -1,10 +0,0 @@
|
||||
|
||||
export default {
|
||||
esm: { type: 'babel' },
|
||||
extraBabelPresets: [
|
||||
require.resolve('./preset'),
|
||||
],
|
||||
extraBabelPlugins: [
|
||||
require.resolve('./p2'),
|
||||
],
|
||||
};
|
@ -1,2 +0,0 @@
|
||||
console.log("p1", "p2", 1);
|
||||
alert(2);
|
@ -1,20 +0,0 @@
|
||||
|
||||
module.exports = function ({ types: t }) {
|
||||
function isConsoleLog(node) {
|
||||
const { callee, callee: { object, property } } = node;
|
||||
return t.isMemberExpression(callee)
|
||||
&& t.isIdentifier(object) && object.name === 'console'
|
||||
&& t.isIdentifier(property) && property.name === 'log';
|
||||
}
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression(path, state) {
|
||||
const { node, node: { callee, callee: { object, property } } } = path;
|
||||
if (isConsoleLog(node)) {
|
||||
node.arguments.unshift(t.stringLiteral('p1'));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
|
||||
module.exports = function ({ types: t }) {
|
||||
function isConsoleLog(node) {
|
||||
const { callee, callee: { object, property } } = node;
|
||||
return t.isMemberExpression(callee)
|
||||
&& t.isIdentifier(object) && object.name === 'console'
|
||||
&& t.isIdentifier(property) && property.name === 'log';
|
||||
}
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression(path, state) {
|
||||
const { node, node: { callee, callee: { object, property } } } = path;
|
||||
if (isConsoleLog(node)) {
|
||||
node.arguments.unshift(t.stringLiteral('p2'));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
|
||||
module.exports = function () {
|
||||
return {
|
||||
plugins: [
|
||||
require.resolve('./p1'),
|
||||
],
|
||||
};
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
|
||||
console.log(1);
|
||||
alert(2);
|
@ -1,5 +0,0 @@
|
||||
|
||||
export default {
|
||||
cjs: { type: 'babel' },
|
||||
esm: { type: 'babel', importLibToEs: true },
|
||||
};
|
@ -1,2 +0,0 @@
|
||||
import foo from "foo/es/foo";
|
||||
console.log(foo());
|
@ -1,3 +0,0 @@
|
||||
import foo from 'foo/lib/foo';
|
||||
|
||||
console.log(foo());
|
@ -1,6 +0,0 @@
|
||||
|
||||
export default {
|
||||
cjs: { type: 'babel' },
|
||||
esm: { type: 'babel' },
|
||||
lessInBabelMode: false,
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
|
||||
import "./index.less";
|
||||
import "./foo.module.less";
|
||||
export default function () {
|
||||
return 'foo';
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
.foo {
|
||||
color: green;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
|
||||
@link-color: green;
|
||||
|
||||
.foo {
|
||||
color: @link-color;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import "./index.less";
|
||||
import "./foo.module.less";
|
||||
|
||||
export default function () {
|
||||
return 'foo';
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
.foo {
|
||||
color: green;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
|
||||
@link-color: green;
|
||||
|
||||
.foo {
|
||||
color: @link-color;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
|
||||
export default {
|
||||
cjs: { type: 'babel' },
|
||||
esm: { type: 'babel' },
|
||||
lessInBabelMode: true,
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
|
||||
import "./index.css";
|
||||
import "./foo.module.css";
|
||||
export default function () {
|
||||
return 'foo';
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
.foo {
|
||||
color: green;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
.foo {
|
||||
color: green;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import "./index.less";
|
||||
import "./foo.module.less";
|
||||
|
||||
export default function () {
|
||||
return 'foo';
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
.foo {
|
||||
color: green;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
|
||||
@link-color: green;
|
||||
|
||||
.foo {
|
||||
color: @link-color;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
|
||||
export default {
|
||||
esm: 'babel',
|
||||
target: 'browser',
|
||||
nodeFiles: [
|
||||
'src/node.js',
|
||||
],
|
||||
}
|
@ -1 +0,0 @@
|
||||
var b = 'foo';
|
@ -1 +0,0 @@
|
||||
const a = 'foo';
|
@ -1,2 +0,0 @@
|
||||
|
||||
const b = 'foo';
|
@ -1,2 +0,0 @@
|
||||
|
||||
const a = 'foo';
|
@ -1,5 +0,0 @@
|
||||
|
||||
export default {
|
||||
esm: 'babel',
|
||||
target: 'node',
|
||||
}
|
@ -1 +0,0 @@
|
||||
declare const b = "foo";
|
@ -1 +0,0 @@
|
||||
var b = 'foo';
|
@ -1 +0,0 @@
|
||||
var b = 'foo';
|
@ -1 +0,0 @@
|
||||
const a = 'foo';
|
@ -1,2 +0,0 @@
|
||||
|
||||
const b = 'foo';
|
@ -1,2 +0,0 @@
|
||||
|
||||
const b = 'foo';
|
@ -1,2 +0,0 @@
|
||||
|
||||
const a = 'foo';
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"esModuleInterop": true,
|
||||
"declaration": true
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
|
||||
export default {
|
||||
cjs: { type: 'babel' },
|
||||
esm: { type: 'babel' },
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
export default function () {
|
||||
return 'foo';
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
import 'bar';
|
||||
import foo from './foo';
|
||||
console.log(foo());
|
@ -1 +0,0 @@
|
||||
export default {};
|
@ -1 +0,0 @@
|
||||
export default {};
|
@ -1 +0,0 @@
|
||||
# bar
|
@ -1 +0,0 @@
|
||||
# bar
|
@ -1,3 +0,0 @@
|
||||
export default function() {
|
||||
return "foo";
|
||||
}
|
@ -1 +0,0 @@
|
||||
{}
|
@ -1,4 +0,0 @@
|
||||
|
||||
export default function () {
|
||||
return 'foo';
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
import 'bar';
|
||||
import foo from './foo';
|
||||
|
||||
console.log(foo());
|
@ -1,6 +0,0 @@
|
||||
|
||||
export default {
|
||||
runtimeHelpers: true,
|
||||
esm: { type: 'babel' },
|
||||
cjs: { type: 'babel' },
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
||||
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
||||
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
||||
|
||||
var A = /*#__PURE__*/function () {
|
||||
function A() {
|
||||
_classCallCheck(this, A);
|
||||
}
|
||||
|
||||
_createClass(A, [{
|
||||
key: "foo",
|
||||
value: function foo() {}
|
||||
}]);
|
||||
|
||||
return A;
|
||||
}();
|
||||
|
||||
new A().foo();
|
||||
var a = {};
|
||||
|
||||
var b = _objectSpread({}, a);
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.10.4"
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
|
||||
class A {
|
||||
foo() {}
|
||||
}
|
||||
|
||||
(new A()).foo();
|
||||
|
||||
const a = {};
|
||||
const b = {...a};
|
@ -1,4 +0,0 @@
|
||||
|
||||
export default {
|
||||
esm: { type: 'rollup' },
|
||||
};
|
@ -1,84 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
}
|
||||
|
||||
function _objectWithoutPropertiesLoose(source, excluded) {
|
||||
if (source == null) return {};
|
||||
var target = {};
|
||||
var sourceKeys = Object.keys(source);
|
||||
var key, i;
|
||||
|
||||
for (i = 0; i < sourceKeys.length; i++) {
|
||||
key = sourceKeys[i];
|
||||
if (excluded.indexOf(key) >= 0) continue;
|
||||
target[key] = source[key];
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
function _objectWithoutProperties(source, excluded) {
|
||||
if (source == null) return {};
|
||||
|
||||
var target = _objectWithoutPropertiesLoose(source, excluded);
|
||||
|
||||
var key, i;
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
||||
|
||||
for (i = 0; i < sourceSymbolKeys.length; i++) {
|
||||
key = sourceSymbolKeys[i];
|
||||
if (excluded.indexOf(key) >= 0) continue;
|
||||
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
function a () {
|
||||
alert('a');
|
||||
}
|
||||
|
||||
function b1() {
|
||||
alert('b1');
|
||||
}
|
||||
function b2() {
|
||||
alert('b2');
|
||||
}
|
||||
|
||||
var b = /*#__PURE__*/Object.freeze({
|
||||
__proto__: null,
|
||||
b1: b1,
|
||||
b2: b2
|
||||
});
|
||||
|
||||
var _class;
|
||||
// babel-plugin-react-require
|
||||
var Foo = function Foo() {
|
||||
return /*#__PURE__*/React.createElement("div", null);
|
||||
}; // Don't support multiple chunks for now
|
||||
// @babel/plugin-syntax-dynamic-import
|
||||
// import('./a');
|
||||
// object-rest-spread
|
||||
|
||||
var _bar = bar,
|
||||
foo = _bar.foo,
|
||||
z = _objectWithoutProperties(_bar, ["foo"]);
|
||||
|
||||
console.log(z); // @babel/plugin-proposal-decorators + class
|
||||
|
||||
var A = foo(_class = function A() {
|
||||
_classCallCheck(this, A);
|
||||
}) || _class; // export default from
|
||||
|
||||
var a$1 = x > 10 ? 'big' : 'small';
|
||||
console.log(a$1); // export namespace from
|
||||
|
||||
export { A, Foo, a, b };
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "^18.0.0"
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
|
||||
export default function () {
|
||||
alert('a');
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
|
||||
export function b1() {
|
||||
alert('b1');
|
||||
}
|
||||
|
||||
export function b2() {
|
||||
alert('b2');
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
|
||||
// babel-plugin-react-require
|
||||
export const Foo = () => <div />;
|
||||
|
||||
// Don't support multiple chunks for now
|
||||
// @babel/plugin-syntax-dynamic-import
|
||||
// import('./a');
|
||||
|
||||
// object-rest-spread
|
||||
const { foo, ...z } = bar;
|
||||
console.log(z);
|
||||
|
||||
// @babel/plugin-proposal-decorators + class
|
||||
@foo
|
||||
export class A {}
|
||||
|
||||
// export default from
|
||||
export a from './a';
|
||||
|
||||
// do expression
|
||||
let a = do {
|
||||
if(x > 10) {
|
||||
'big';
|
||||
} else {
|
||||
'small';
|
||||
}
|
||||
};
|
||||
console.log(a);
|
||||
|
||||
// export namespace from
|
||||
export * as b from './b';
|
||||
|
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
cjs: { type: 'babel' },
|
||||
esm: { type: 'babel' },
|
||||
};
|
@ -1,2 +0,0 @@
|
||||
export declare const optionalChaining: string;
|
||||
export declare const nullishCoalescing: string | boolean;
|
@ -1,6 +0,0 @@
|
||||
var _foo$test;
|
||||
|
||||
var foo = {};
|
||||
export var optionalChaining = foo === null || foo === void 0 ? void 0 : (_foo$test = foo.test) === null || _foo$test === void 0 ? void 0 : _foo$test.abc;
|
||||
var bar = false;
|
||||
export var nullishCoalescing = bar !== null && bar !== void 0 ? bar : 'default';
|
@ -1,11 +0,0 @@
|
||||
type Foo = {
|
||||
test?: {
|
||||
abc?: string;
|
||||
}
|
||||
}
|
||||
const foo: Foo = {};
|
||||
|
||||
export const optionalChaining = foo?.test?.abc;
|
||||
|
||||
const bar = false;
|
||||
export const nullishCoalescing = bar ?? 'default';
|
@ -1,6 +0,0 @@
|
||||
|
||||
export default {
|
||||
cjs: { type: 'babel' },
|
||||
esm: { type: 'babel' },
|
||||
disableTypeCheck: true,
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
export default function foo(opts) {
|
||||
return opts.foo ? 'foo' : 'bar';
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
interface IOpts {
|
||||
foo: boolean;
|
||||
}
|
||||
|
||||
export default function foo(opts: IOpts): string {
|
||||
return opts.foo ? 'foo' : 'bar';
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user