6410bc8a75
* feat: nocobase build * chore: update build scripts * chore: update build scripts * chore(versions): 😊 publish v0.7.0-alpha.33 * chore: independent version * chore: nocobase build * chore(versions): 😊 publish v0.7.0-alpha.34 * feat: nocobase-cli * feat: nocobase-cli * chore: update dependencies * feat: improve code * refactor: create-nocobase-app * chore(versions): 😊 publish v0.7.0-alpha.35 * feat: @nocobase/devtools * chore(versions): 😊 publish v0.7.0-alpha.36 * chore: update dependencies * chore(versions): 😊 publish v0.7.0-alpha.37 * feat: improve code * chore(versions): 😊 publish v0.7.0-alpha.38 * feat: improve code * chore(versions): 😊 publish v0.7.0-alpha.39 * feat: update deps * chore(versions): 😊 publish v0.7.0-alpha.40 * chore: update devDependencies * chore(versions): 😊 publish v0.7.0-alpha.41 * fix: postinstall * chore(versions): 😊 publish v0.7.0-alpha.42 * chore: improve code * chore(versions): 😊 publish v0.7.0-alpha.43 * chore: execa * chore(versions): 😊 publish v0.7.0-alpha.44 * chore(cli): allow unknown option * chore(versions): 😊 publish v0.7.0-alpha.45 * fix: default envs * chore(versions): 😊 publish v0.7.0-alpha.45 * fix: package argument for build command * chore(versions): 😊 publish v0.7.0-alpha.46 * fix: improve code * chore(versions): 😊 publish v0.7.0-alpha.48 * feat: clean & doc * chore(versions): 😊 publish v0.7.0-alpha.49 * feat: compilation tips * feat: upgrade command * chore(versions): 😊 publish v0.7.0-alpha.50 * fix: unexpected token ] in JSON * chore(versions): 😊 publish v0.7.0-alpha.51 * fix: upgrade command * chore(versions): 😊 publish v0.7.0-alpha.52 * fix: remove export action from available action * fix: db sync after upgrade * chore(versions): 😊 publish v0.7.0-alpha.53 * feat: upgrade log * chore(versions): 😊 publish v0.7.0-alpha.54 * docs: updates * feat: updates * docs(cli): update usage description * feat: updates * docs: updates * docs: updates * docs: toc * feat: sdk * docs: updates * docs: updates * docs: updates * Update index.md * docs: updates * Update release-notes.md * Update roadmap.md * Update index.md * Update contributing.md * Update contributing.md * Update index.md * Update index.md * Update nocobase-cli.md * Update nocobase-cli.md * fix: user plugin initialization data * Update env.md * Update env.md * Update directory-structure.md * Update index.md * Update action-api.md * Update filter-operators.md * docs: update thanks.md * Update index.md * Update javascript-sdk.md * Update rest-api.md * Update installation.md * Update installation.md * Update upgrading.md * Update upgrading.md * Update upgrading.md * Update installation.md * Update installation.md * Create release-notes.md * Update release-notes.md * feat: updates * feat: update docs * feat: update release-notes.md * feat: switch language * feat: updates * Add files via upload * Add files via upload * Update important-features.md * Update thanks.md * feat: nocobase postinstall * Update index.md * Create why-different.md * Update why-different.md * Create who-is-for.md * Rename who-is-for.md to who.md * feat: update docs * Rename why-different.md to why.md * Update why.md * Update menus.ts * Update why-nocobase.md * Create who.md * Create why.md * feat: updates * chore(versions): 😊 publish v0.7.0-alpha.55 * feat: tips * Update who.md * Update who.md * feat: update docs * feat: update doc menus * fix: plugin client dist * docs: update contributing.md * docs: update readme.md * docs: update readme.md * docs: update readme.md * Update functional-zoning.md * fix: br Co-authored-by: Zhou <zhou.working@gmail.com>
344 lines
11 KiB
TypeScript
Executable File
344 lines
11 KiB
TypeScript
Executable File
import { existsSync } from 'fs'
|
||
import { basename, extname, join } from 'path';
|
||
import { ModuleFormat, RollupOptions, Plugin } from 'rollup';
|
||
import url from '@rollup/plugin-url';
|
||
import json from '@rollup/plugin-json';
|
||
import replace from '@rollup/plugin-replace';
|
||
import commonjs from '@rollup/plugin-commonjs';
|
||
import nodeResolve from '@rollup/plugin-node-resolve';
|
||
import inject, { RollupInjectOptions } from '@rollup/plugin-inject';
|
||
import babel, { RollupBabelInputPluginOptions } from '@rollup/plugin-babel';
|
||
import { createFilter } from '@rollup/pluginutils';
|
||
import postcss from 'rollup-plugin-postcss';
|
||
import { terser } from 'rollup-plugin-terser';
|
||
import typescript2 from 'rollup-plugin-typescript2';
|
||
import { camelCase } from 'lodash';
|
||
import tempDir from 'temp-dir';
|
||
import autoprefixer from 'autoprefixer';
|
||
import NpmImport from 'less-plugin-npm-import';
|
||
import svgr from '@svgr/rollup';
|
||
import getBabelConfig from './getBabelConfig';
|
||
import { getPkgPath, shouldTransform } from './es5ImcompatibleVersions';
|
||
import { IBundleOptions } from './types';
|
||
|
||
interface IGetRollupConfigOpts {
|
||
cwd: string;
|
||
rootPath: string;
|
||
entry: string;
|
||
type: ModuleFormat;
|
||
importLibToEs?: boolean;
|
||
bundleOpts: IBundleOptions;
|
||
}
|
||
|
||
interface IPkg {
|
||
dependencies?: Object;
|
||
peerDependencies?: Object;
|
||
name?: string;
|
||
}
|
||
|
||
export default function(opts: IGetRollupConfigOpts): RollupOptions[] {
|
||
const { type, entry, cwd, rootPath, importLibToEs, bundleOpts } = opts;
|
||
const {
|
||
umd,
|
||
esm,
|
||
cjs,
|
||
file,
|
||
target = 'browser',
|
||
extractCSS = false,
|
||
injectCSS = true,
|
||
cssModules: modules,
|
||
extraPostCSSPlugins = [],
|
||
extraBabelPresets = [],
|
||
extraBabelPlugins = [],
|
||
extraRollupPlugins = [],
|
||
autoprefixer: autoprefixerOpts,
|
||
include = /node_modules/,
|
||
runtimeHelpers: runtimeHelpersOpts,
|
||
replace: replaceOpts,
|
||
inject: injectOpts,
|
||
extraExternals = [],
|
||
externalsExclude = [],
|
||
nodeVersion,
|
||
typescriptOpts,
|
||
nodeResolveOpts = {},
|
||
disableTypeCheck,
|
||
lessInRollupMode = {},
|
||
sassInRollupMode = {},
|
||
} = bundleOpts;
|
||
const entryExt = extname(entry);
|
||
const name = file || basename(entry, entryExt);
|
||
const isTypeScript = entryExt === '.ts' || entryExt === '.tsx';
|
||
const extensions = ['.js', '.jsx', '.ts', '.tsx', '.es6', '.es', '.mjs'];
|
||
|
||
let pkg = {} as IPkg;
|
||
try {
|
||
pkg = require(join(cwd, 'package.json')); // eslint-disable-line
|
||
} catch (e) {}
|
||
|
||
// cjs 不给浏览器用,所以无需 runtimeHelpers
|
||
const runtimeHelpers = type === 'cjs' ? false : runtimeHelpersOpts;
|
||
const babelOpts = {
|
||
...(getBabelConfig({
|
||
type,
|
||
target: type === 'esm' ? 'browser' : target,
|
||
// watch 模式下有几率走的 babel?原因未知。
|
||
// ref: https://github.com/umijs/father/issues/158
|
||
typescript: true,
|
||
runtimeHelpers,
|
||
nodeVersion,
|
||
}).opts),
|
||
// ref: https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers
|
||
babelHelpers: (runtimeHelpers ? 'runtime' : 'bundled') as RollupBabelInputPluginOptions['babelHelpers'],
|
||
// exclude: /\/node_modules\//,
|
||
filter: (filePath: string) => {
|
||
const rollupFilter = createFilter(null, /\/node_modules\//);
|
||
// 默认过滤 node_modules
|
||
if (!rollupFilter(filePath)) {
|
||
const pkgPath = getPkgPath(filePath);
|
||
return shouldTransform(pkgPath);
|
||
}
|
||
return true;
|
||
},
|
||
babelrc: false,
|
||
// ref: https://github.com/rollup/rollup-plugin-babel#usage
|
||
extensions,
|
||
};
|
||
if (importLibToEs && type === 'esm') {
|
||
babelOpts.plugins.push(require.resolve('../lib/importLibToEs'));
|
||
}
|
||
babelOpts.presets.push(...extraBabelPresets);
|
||
babelOpts.plugins.push(...extraBabelPlugins);
|
||
|
||
// rollup configs
|
||
const input = join(cwd, entry);
|
||
const format = type;
|
||
|
||
// ref: https://rollupjs.org/guide/en#external
|
||
// 潜在问题:引用包的子文件时会报 warning,比如 @babel/runtime/helpers/esm/createClass
|
||
// 解决方案:可以用 function 处理
|
||
const external = [
|
||
...Object.keys(pkg.dependencies || {}),
|
||
...Object.keys(pkg.peerDependencies || {}),
|
||
...extraExternals,
|
||
];
|
||
// umd 只要 external peerDependencies
|
||
const externalPeerDeps = [
|
||
...Object.keys(pkg.peerDependencies || {}),
|
||
...extraExternals,
|
||
];
|
||
|
||
function getPkgNameByid(id) {
|
||
const splitted = id.split('/');
|
||
// @ 和 @tmp 是为了兼容 umi 的逻辑
|
||
if (id.charAt(0) === '@' && splitted[0] !== '@' && splitted[0] !== '@tmp') {
|
||
return splitted
|
||
.slice(0, 2)
|
||
.join('/');
|
||
} else {
|
||
return id.split('/')[0];
|
||
}
|
||
}
|
||
|
||
function testExternal(pkgs, excludes, id) {
|
||
if (excludes.includes(id)) {
|
||
return false;
|
||
}
|
||
return pkgs.includes(getPkgNameByid(id));
|
||
}
|
||
|
||
const terserOpts = {
|
||
compress: {
|
||
pure_getters: true,
|
||
unsafe: true,
|
||
unsafe_comps: true,
|
||
warnings: false,
|
||
},
|
||
};
|
||
|
||
// https://github.com/umijs/father/issues/164
|
||
function mergePlugins(defaultRollupPlugins: Array<Plugin> = [], extraRollupPlugins: Array<Plugin> = []) {
|
||
const pluginsMap: Record<string, Plugin> = Object.assign(
|
||
defaultRollupPlugins.reduce((r, plugin) => ({ ...r, [plugin.name]: plugin }), {}),
|
||
extraRollupPlugins.reduce((r, plugin) => ({ ...r, [plugin.name]: plugin }), {}),
|
||
);
|
||
return Object.values(pluginsMap);
|
||
}
|
||
|
||
function getPlugins(opts = {} as { minCSS: boolean; }) {
|
||
const { minCSS } = opts;
|
||
const defaultRollupPlugins = [
|
||
url(),
|
||
svgr(),
|
||
postcss({
|
||
extract: extractCSS,
|
||
inject: injectCSS,
|
||
modules,
|
||
// modules => all .less will convert into css modules
|
||
...(modules ? { autoModules: false } : {}),
|
||
minimize: !!minCSS,
|
||
use: {
|
||
less: {
|
||
plugins: [new NpmImport({ prefix: '~' })],
|
||
javascriptEnabled: true,
|
||
...lessInRollupMode
|
||
},
|
||
sass: {
|
||
...sassInRollupMode,
|
||
},
|
||
stylus: false,
|
||
},
|
||
plugins: [autoprefixer({
|
||
// https://github.com/postcss/autoprefixer/issues/776
|
||
remove: false,
|
||
...autoprefixerOpts,
|
||
}), ...extraPostCSSPlugins],
|
||
}),
|
||
...(injectOpts ? [inject(injectOpts as RollupInjectOptions)] : []),
|
||
...(replaceOpts && Object.keys(replaceOpts || {}).length ? [replace(replaceOpts)] : []),
|
||
nodeResolve({
|
||
mainFields: ['module', 'jsnext:main', 'main'],
|
||
extensions,
|
||
...nodeResolveOpts,
|
||
}),
|
||
...(isTypeScript
|
||
? [
|
||
typescript2({
|
||
cwd,
|
||
// @see https://github.com/umijs/father/issues/61#issuecomment-544822774
|
||
clean: true,
|
||
cacheRoot: `${tempDir}/.rollup_plugin_typescript2_cache`,
|
||
// 支持往上找 tsconfig.json
|
||
// 比如 lerna 的场景不需要每个 package 有个 tsconfig.json
|
||
tsconfig: [join(cwd, 'tsconfig.json'), join(rootPath, 'tsconfig.json')].find(existsSync),
|
||
tsconfigDefaults: {
|
||
compilerOptions: {
|
||
// Generate declaration files by default
|
||
declaration: true,
|
||
},
|
||
},
|
||
tsconfigOverride: {
|
||
compilerOptions: {
|
||
// Support dynamic import
|
||
target: 'esnext',
|
||
},
|
||
},
|
||
check: !disableTypeCheck,
|
||
...(typescriptOpts || {}),
|
||
}),
|
||
]
|
||
: []),
|
||
babel(babelOpts),
|
||
json(),
|
||
];
|
||
return mergePlugins(defaultRollupPlugins, extraRollupPlugins || []);
|
||
}
|
||
|
||
switch (type) {
|
||
case 'esm':
|
||
const output: Record<string, any> = {
|
||
dir: join(cwd, `${esm && (esm as any).dir || 'dist'}`),
|
||
entryFileNames: `${(esm && (esm as any).file) || `${name}.esm`}.js`,
|
||
}
|
||
|
||
return [
|
||
{
|
||
input,
|
||
output: {
|
||
format,
|
||
...output,
|
||
},
|
||
plugins: [...getPlugins(), ...(esm && (esm as any).minify ? [terser(terserOpts)] : [])],
|
||
external: testExternal.bind(null, external, externalsExclude),
|
||
},
|
||
...(esm && (esm as any).mjs
|
||
? [
|
||
{
|
||
input,
|
||
output: {
|
||
format,
|
||
file: join(cwd, `dist/${(esm && (esm as any).file) || `${name}`}.mjs`),
|
||
},
|
||
plugins: [
|
||
...getPlugins(),
|
||
replace({
|
||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||
}),
|
||
terser(terserOpts),
|
||
],
|
||
external: testExternal.bind(null, externalPeerDeps, externalsExclude),
|
||
},
|
||
]
|
||
: []),
|
||
];
|
||
|
||
case 'cjs':
|
||
return [
|
||
{
|
||
input,
|
||
output: {
|
||
format,
|
||
file: join(cwd, `dist/${(cjs && (cjs as any).file) || name}.js`),
|
||
},
|
||
plugins: [...getPlugins(), ...(cjs && (cjs as any).minify ? [terser(terserOpts)] : [])],
|
||
external: testExternal.bind(null, external, externalsExclude),
|
||
},
|
||
];
|
||
|
||
case 'umd':
|
||
// Add umd related plugins
|
||
const extraUmdPlugins = [
|
||
commonjs({
|
||
include,
|
||
// namedExports options has been remove from https://github.com/rollup/plugins/pull/149
|
||
}),
|
||
];
|
||
|
||
return [
|
||
{
|
||
input,
|
||
output: {
|
||
format,
|
||
sourcemap: umd && umd.sourcemap,
|
||
file: join(cwd, `dist/${(umd && umd.file) || `${name}.umd`}.js`),
|
||
globals: umd && umd.globals,
|
||
name: (umd && umd.name) || (pkg.name && camelCase(basename(pkg.name))),
|
||
},
|
||
plugins: [
|
||
...extraUmdPlugins,
|
||
...getPlugins(),
|
||
replace({
|
||
'process.env.NODE_ENV': JSON.stringify('development'),
|
||
}),
|
||
],
|
||
external: testExternal.bind(null, externalPeerDeps, externalsExclude),
|
||
},
|
||
...(umd && umd.minFile === false
|
||
? []
|
||
: [
|
||
{
|
||
input,
|
||
output: {
|
||
format,
|
||
sourcemap: umd && umd.sourcemap,
|
||
file: join(cwd, `dist/${(umd && umd.file) || `${name}.umd`}.min.js`),
|
||
globals: umd && umd.globals,
|
||
name: (umd && umd.name) || (pkg.name && camelCase(basename(pkg.name))),
|
||
},
|
||
plugins: [
|
||
...extraUmdPlugins,
|
||
...getPlugins({ minCSS: true }),
|
||
replace({
|
||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||
}),
|
||
terser(terserOpts),
|
||
],
|
||
external: testExternal.bind(null, externalPeerDeps, externalsExclude),
|
||
},
|
||
]),
|
||
];
|
||
|
||
default:
|
||
throw new Error(`Unsupported type ${type}`);
|
||
}
|
||
}
|