mirror of https://github.com/alibaba/ice.git
feat: basic icejs cli
This commit is contained in:
parent
2ff30ae6d6
commit
7c665bee30
|
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "basic-project",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "../../packages/icejs/bin/ice-cli.js start",
|
||||
"build": "../../packages/icejs/bin/ice-cli.js build"
|
||||
},
|
||||
"description": "",
|
||||
"author": "",
|
||||
"license": "MIT"
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="ice-container"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1 @@
|
|||
console.log('test');
|
||||
|
|
@ -26,9 +26,9 @@
|
|||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/glob": "^7.2.0",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^17.0.12",
|
||||
"@types/node": "^17.0.13",
|
||||
"@types/semver": "^7.3.9",
|
||||
"chalk": "^5.0.0",
|
||||
"chalk": "^4.1.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"dependency-check": "^4.1.0",
|
||||
"eslint": "^8.7.0",
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
"prettier-plugin-organize-imports": "^2.3.4",
|
||||
"prettier-plugin-packagejson": "^2.2.15",
|
||||
"puppeteer": "^13.1.2",
|
||||
"react": "^17.0.0",
|
||||
"react": "^17.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.3.5",
|
||||
"stylelint": "^14.3.0",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env node
|
||||
const utils = require('create-cli-utils');
|
||||
const getBuiltInPlugins = require('../lib/getBuiltInPlugins').default;
|
||||
|
||||
(async () => {
|
||||
await utils.childProcessStart(getBuiltInPlugins);
|
||||
})();
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const projectRootDir = process.env.INIT_CWD; // the original working directory that npm was executed from
|
||||
if (!projectRootDir) {
|
||||
// process.env.INIT_CWD may be undefined in low version npm or cnpm
|
||||
return;
|
||||
}
|
||||
|
||||
const iceTempDir = path.join(projectRootDir, '.ice');
|
||||
const iceTempDtsBundlePath = path.join(iceTempDir, 'index.d.ts');
|
||||
const dtsBundlePath = path.join(__dirname, '..', 'lib', 'ice.d.ts');
|
||||
|
||||
if (fs.existsSync(dtsBundlePath)) {
|
||||
if (!fs.existsSync(iceTempDir)) {
|
||||
fs.mkdirSync(iceTempDir);
|
||||
}
|
||||
|
||||
fs.copyFileSync(
|
||||
dtsBundlePath,
|
||||
iceTempDtsBundlePath,
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env node
|
||||
const utils = require('create-cli-utils');
|
||||
const getBuiltInPlugins = require('../lib/getBuiltInPlugins').default;
|
||||
const packageInfo = require('../package.json');
|
||||
|
||||
const forkChildProcessPath = require.resolve('./child-process-start');
|
||||
|
||||
(async () => {
|
||||
await utils.createCli(getBuiltInPlugins, forkChildProcessPath, packageInfo);
|
||||
})();
|
||||
|
|
@ -7,5 +7,16 @@
|
|||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "ice-admin",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@builder/pack": "^0.6.0",
|
||||
"build-plugin-app": "^1.0.0",
|
||||
"build-scripts": "^1.2.1",
|
||||
"chalk": "^4.0.0",
|
||||
"create-cli-utils": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.22.0",
|
||||
"npm": ">=3.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
import type { IGetBuiltInPlugins, IPluginList, IUserConfig, Json } from 'build-scripts';
|
||||
import { hijackWebpack } from './requireHook';
|
||||
import chalk from 'chalk';
|
||||
|
||||
const getDynamicPlugins = (userConfig: IUserConfig) => {
|
||||
const { plugins } = userConfig;
|
||||
const dynamicPlugins: [string, string, boolean][] = [
|
||||
/* ['build-plugin-ice-ssr', 'ssr', false],
|
||||
['build-plugin-ice-store', 'store', true],
|
||||
['build-plugin-ice-auth', 'auth', true],
|
||||
['build-plugin-pwa', 'pwa', false],
|
||||
['build-plugin-ice-request', 'request', true], */
|
||||
];
|
||||
|
||||
const checkPluginExist = (name: string) => {
|
||||
return plugins && plugins.some(plugin => {
|
||||
if (typeof plugin === 'string') {
|
||||
return plugin === name;
|
||||
} else if (Array.isArray(plugin)) {
|
||||
return plugin[0] === name;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return dynamicPlugins
|
||||
.filter(([pluginName, configKey, defaultValue]) => {
|
||||
const exist = checkPluginExist(pluginName);
|
||||
if (exist) {
|
||||
console.log('');
|
||||
console.log(chalk.magenta(`The ${pluginName} has been built in. Please remove it from build.json.`));
|
||||
console.log('');
|
||||
} else {
|
||||
return Object.prototype.hasOwnProperty.call(userConfig, configKey) ? userConfig[configKey] : defaultValue;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.map(([name]) => name);
|
||||
};
|
||||
|
||||
const getBuiltInPlugins: IGetBuiltInPlugins = (userConfig) => {
|
||||
// enable webpack 5 by default
|
||||
hijackWebpack();
|
||||
// eslint-disable-next-line
|
||||
const pkg = require('../package.json');
|
||||
process.env.__FRAMEWORK_VERSION__ = pkg.version;
|
||||
const coreOptions = {
|
||||
framework: 'react',
|
||||
alias: process.env.__FRAMEWORK_NAME__ || 'ice',
|
||||
} as Json;
|
||||
let plugins: IPluginList = [
|
||||
// common plugins
|
||||
// ['build-plugin-app-core', coreOptions],
|
||||
// 'build-plugin-ice-logger',
|
||||
|
||||
// react base plugin
|
||||
require.resolve('build-plugin-app'),
|
||||
|
||||
// for ice/react plugins
|
||||
/* 'build-plugin-ice-router',
|
||||
'build-plugin-ice-config',
|
||||
'build-plugin-ice-mpa',
|
||||
'build-plugin-helmet',
|
||||
'build-plugin-speed', */
|
||||
];
|
||||
|
||||
if (userConfig.mpa && userConfig.router === false) {
|
||||
console.warn('Warning:', 'MPA 模式下 router: false 选项没有意义,建议移除该选项。');
|
||||
}
|
||||
|
||||
if (!userConfig.mpa && userConfig.router === false) {
|
||||
// SPA 并且设置了 router: false 则过滤 router 插件
|
||||
plugins = plugins.filter((name) => name !== 'build-plugin-ice-router');
|
||||
}
|
||||
|
||||
const dynamicPlugins = getDynamicPlugins(userConfig);
|
||||
|
||||
return plugins.concat(dynamicPlugins);
|
||||
};
|
||||
|
||||
export default getBuiltInPlugins;
|
||||
|
|
@ -1 +1,13 @@
|
|||
export default () => 'ice';
|
||||
import * as utils from 'create-cli-utils';
|
||||
import getBuiltInPlugins from './getBuiltInPlugins';
|
||||
|
||||
console.log('getBuiltInPlugins', getBuiltInPlugins);
|
||||
|
||||
module.exports = (frameworkName: string, { packageInfo, extendCli }) => {
|
||||
// eslint-disable-next-line global-require
|
||||
const pkg = require('../package.json');
|
||||
const forkChildProcessPath = require.resolve('../bin/child-process-start');
|
||||
process.env.__FRAMEWORK_NAME__ = frameworkName;
|
||||
packageInfo.__ICEJS_INFO__ = { name: pkg.name, version: pkg.version };
|
||||
utils.createCli(getBuiltInPlugins, forkChildProcessPath, packageInfo, extendCli);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
// inspired by https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack/require-hook.ts
|
||||
|
||||
// sync injects a hook for webpack and webpack/... requires to use the internal ncc webpack version
|
||||
// this is in order for userland plugins to attach to the same webpack instance as next.js
|
||||
// the individual compiled modules are as defined for the compilation in bundles/webpack/packages/*
|
||||
export function getFileName(filePath: string) {
|
||||
return filePath.split('/').slice(-1)[0];
|
||||
}
|
||||
|
||||
export function getHookFiles() {
|
||||
const webpackPlugins = [
|
||||
'webpack/lib/Compilation',
|
||||
'webpack/lib/dependencies/ConstDependency',
|
||||
'webpack/lib/javascript/JavascriptParserHelpers',
|
||||
'webpack/lib/LibraryTemplatePlugin',
|
||||
'webpack/lib/LoaderTargetPlugin',
|
||||
'webpack/lib/node/NodeTargetPlugin',
|
||||
'webpack/lib/node/NodeTemplatePlugin',
|
||||
'webpack/lib/NormalModule',
|
||||
'webpack/lib/RequestShortener',
|
||||
'webpack/lib/RuntimeGlobals',
|
||||
'webpack/lib/RuntimeModule',
|
||||
'webpack/lib/optimize/LimitChunkCountPlugin',
|
||||
'webpack/lib/ParserHelpers',
|
||||
'webpack/lib/SingleEntryPlugin',
|
||||
'webpack/lib/Template',
|
||||
'webpack/lib/webworker/WebWorkerTemplatePlugin',
|
||||
'webpack/lib/node/NodeEnvironmentPlugin',
|
||||
'webpack/lib/BasicEvaluatedExpression',
|
||||
'webpack/lib/ModuleFilenameHelpers',
|
||||
'webpack/lib/GraphHelpers',
|
||||
'webpack/lib/ExternalsPlugin',
|
||||
'webpack/lib/web/FetchCompileAsyncWasmPlugin',
|
||||
'webpack/lib/web/FetchCompileWasmPlugin',
|
||||
'webpack/lib/ProgressPlugin',
|
||||
];
|
||||
const pluginMap = webpackPlugins.map((pluginPath) => {
|
||||
const pluginName = getFileName(pluginPath);
|
||||
return [pluginPath, `@builder/pack/deps/webpack/${pluginName}`];
|
||||
});
|
||||
|
||||
return [
|
||||
['webpack-dev-server', '@builder/pack/deps/webpack-dev-server'],
|
||||
['webpack', '@builder/pack/deps/webpack/webpack-lib'],
|
||||
['webpack/package', '@builder/pack/deps/webpack/package'],
|
||||
['webpack/package.json', '@builder/pack/deps/webpack/package'],
|
||||
['webpack/lib/webpack', '@builder/pack/deps/webpack/webpack-lib'],
|
||||
['webpack/lib/webpack.js', '@builder/pack/deps/webpack/webpack-lib'],
|
||||
['webpack-sources', '@builder/pack/deps/webpack/sources'],
|
||||
['webpack-sources/lib', '@builder/pack/deps/webpack/sources'],
|
||||
['webpack-sources/lib/index', '@builder/pack/deps/webpack/sources'],
|
||||
['webpack-sources/lib/index.js', '@builder/pack/deps/webpack/sources'],
|
||||
['webpack/hot/dev-server', '@builder/pack/deps/webpack/hot/dev-server'],
|
||||
['webpack/hot/only-dev-server', '@builder/pack/deps/webpack/hot/only-dev-server'],
|
||||
['webpack/hot/emitter', '@builder/pack/deps/webpack/hot/emitter'],
|
||||
...pluginMap,
|
||||
];
|
||||
}
|
||||
|
||||
export function hijackWebpack() {
|
||||
const hookPropertyMap = new Map(
|
||||
getHookFiles().map(([request, replacement]) => [request, require.resolve(replacement)]),
|
||||
);
|
||||
// eslint-disable-next-line global-require
|
||||
const mod = require('module');
|
||||
const resolveFilename = mod._resolveFilename;
|
||||
mod._resolveFilename = function (
|
||||
request: string,
|
||||
parent: any,
|
||||
isMain: boolean,
|
||||
options: any,
|
||||
) {
|
||||
const hookResolved = hookPropertyMap.get(request);
|
||||
if (hookResolved) request = hookResolved;
|
||||
return resolveFilename.call(mod, request, parent, isMain, options);
|
||||
};
|
||||
}
|
||||
|
|
@ -1,15 +1,23 @@
|
|||
{
|
||||
"name": "plugin-app",
|
||||
"name": "build-plugin-app",
|
||||
"version": "1.0.0",
|
||||
"description": "plugin app",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@builder/pack": "^0.6.0",
|
||||
"@builder/webpack-config": "^2.0.0",
|
||||
"events": "^3.3.0"
|
||||
},
|
||||
"author": "ice-admin",
|
||||
"files": [
|
||||
"runtime",
|
||||
"lib"
|
||||
],
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"build-scripts": "^1.2.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,22 @@
|
|||
export default () => 'plugin';
|
||||
import * as path from 'path';
|
||||
import getWebpackConfig from '@builder/webpack-config';
|
||||
import type { IPlugin } from 'build-scripts';
|
||||
|
||||
const plugin: IPlugin = ({ registerTask, context }) => {
|
||||
const { command, rootDir } = context;
|
||||
const mode = command === 'start' ? 'development' : 'production';
|
||||
const webpackConfig = getWebpackConfig(mode);
|
||||
// set alias for webpack/hot while webpack has been prepacked
|
||||
webpackConfig.resolve.alias.set('webpack/hot', '@builder/pack/deps/webpack/hot');
|
||||
// TODO: remove after refactor
|
||||
webpackConfig.entry('index').add(path.join(rootDir, 'src/app'));
|
||||
webpackConfig.resolve.merge({
|
||||
fallback: {
|
||||
// add events fallback for webpack/hot/emitter
|
||||
events: require.resolve('events'),
|
||||
},
|
||||
});
|
||||
registerTask('web', webpackConfig);
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@ import ice from '../src/index';
|
|||
|
||||
describe('basic test', () => {
|
||||
it('test return value', () => {
|
||||
expect(ice()).toBe('plugin');
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
});
|
||||
1868
pnpm-lock.yaml
1868
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue