@spcsn/taro-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +174 -0
- package/README.md +0 -0
- package/bin/taro +7 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +266 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/customCommand.d.ts +5 -0
- package/dist/commands/customCommand.js +23 -0
- package/dist/commands/customCommand.js.map +1 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.js +10 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/packagesManagement.d.ts +19 -0
- package/dist/config/packagesManagement.js +22 -0
- package/dist/config/packagesManagement.js.map +1 -0
- package/dist/create/constants.d.ts +1 -0
- package/dist/create/constants.js +5 -0
- package/dist/create/constants.js.map +1 -0
- package/dist/create/creator.d.ts +9 -0
- package/dist/create/creator.js +64 -0
- package/dist/create/creator.js.map +1 -0
- package/dist/create/fetchTemplate.d.ts +8 -0
- package/dist/create/fetchTemplate.js +169 -0
- package/dist/create/fetchTemplate.js.map +1 -0
- package/dist/create/page.d.ts +65 -0
- package/dist/create/page.js +266 -0
- package/dist/create/page.js.map +1 -0
- package/dist/create/plugin.d.ts +16 -0
- package/dist/create/plugin.js +77 -0
- package/dist/create/plugin.js.map +1 -0
- package/dist/create/project.d.ts +70 -0
- package/dist/create/project.js +481 -0
- package/dist/create/project.js.map +1 -0
- package/dist/doctor/index.d.ts +4 -0
- package/dist/doctor/index.js +23 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/presets/commands/build.d.ts +3 -0
- package/dist/presets/commands/build.js +236 -0
- package/dist/presets/commands/build.js.map +1 -0
- package/dist/presets/commands/config.d.ts +3 -0
- package/dist/presets/commands/config.js +121 -0
- package/dist/presets/commands/config.js.map +1 -0
- package/dist/presets/commands/create.d.ts +3 -0
- package/dist/presets/commands/create.js +112 -0
- package/dist/presets/commands/create.js.map +1 -0
- package/dist/presets/commands/global-config.d.ts +3 -0
- package/dist/presets/commands/global-config.js +175 -0
- package/dist/presets/commands/global-config.js.map +1 -0
- package/dist/presets/commands/help.d.ts +3 -0
- package/dist/presets/commands/help.js +16 -0
- package/dist/presets/commands/help.js.map +1 -0
- package/dist/presets/commands/info.d.ts +3 -0
- package/dist/presets/commands/info.js +96 -0
- package/dist/presets/commands/info.js.map +1 -0
- package/dist/presets/commands/init.d.ts +3 -0
- package/dist/presets/commands/init.js +46 -0
- package/dist/presets/commands/init.js.map +1 -0
- package/dist/presets/commands/inspect.d.ts +3 -0
- package/dist/presets/commands/inspect.js +155 -0
- package/dist/presets/commands/inspect.js.map +1 -0
- package/dist/presets/commands/update.d.ts +3 -0
- package/dist/presets/commands/update.js +187 -0
- package/dist/presets/commands/update.js.map +1 -0
- package/dist/presets/constant/hooks.d.ts +13 -0
- package/dist/presets/constant/hooks.js +17 -0
- package/dist/presets/constant/hooks.js.map +1 -0
- package/dist/presets/constant/index.d.ts +1 -0
- package/dist/presets/constant/index.js +18 -0
- package/dist/presets/constant/index.js.map +1 -0
- package/dist/presets/files/generateFrameworkInfo.d.ts +3 -0
- package/dist/presets/files/generateFrameworkInfo.js +30 -0
- package/dist/presets/files/generateFrameworkInfo.js.map +1 -0
- package/dist/presets/files/generateProjectConfig.d.ts +3 -0
- package/dist/presets/files/generateProjectConfig.js +72 -0
- package/dist/presets/files/generateProjectConfig.js.map +1 -0
- package/dist/presets/files/writeFileToDist.d.ts +3 -0
- package/dist/presets/files/writeFileToDist.js +50 -0
- package/dist/presets/files/writeFileToDist.js.map +1 -0
- package/dist/presets/hooks/build.d.ts +3 -0
- package/dist/presets/hooks/build.js +55 -0
- package/dist/presets/hooks/build.js.map +1 -0
- package/dist/presets/hooks/create.d.ts +3 -0
- package/dist/presets/hooks/create.js +42 -0
- package/dist/presets/hooks/create.js.map +1 -0
- package/dist/presets/index.d.ts +4 -0
- package/dist/presets/index.js +50 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/platforms/plugin.d.ts +3 -0
- package/dist/presets/platforms/plugin.js +106 -0
- package/dist/presets/platforms/plugin.js.map +1 -0
- package/dist/presets/platforms/rn.d.ts +3 -0
- package/dist/presets/platforms/rn.js +130 -0
- package/dist/presets/platforms/rn.js.map +1 -0
- package/dist/util/appConfig.d.ts +11 -0
- package/dist/util/appConfig.js +27 -0
- package/dist/util/appConfig.js.map +1 -0
- package/dist/util/createPage.d.ts +9 -0
- package/dist/util/createPage.js +114 -0
- package/dist/util/createPage.js.map +1 -0
- package/dist/util/defineConfig.d.ts +17 -0
- package/dist/util/defineConfig.js +11 -0
- package/dist/util/defineConfig.js.map +1 -0
- package/dist/util/index.d.ts +23 -0
- package/dist/util/index.js +149 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/types.d.ts +58 -0
- package/dist/util/types.js +3 -0
- package/dist/util/types.js.map +1 -0
- package/global.d.ts +4 -0
- package/index.js +3 -0
- package/package.json +74 -0
- package/postinstall.js +17 -0
- package/src/__tests__/__mocks__/presets.ts +15 -0
- package/src/__tests__/build-config.spec.ts +66 -0
- package/src/__tests__/cli.spec.ts +226 -0
- package/src/__tests__/config.spec.ts +224 -0
- package/src/__tests__/doctor-config.spec.ts +943 -0
- package/src/__tests__/doctor-recommand.spec.ts +136 -0
- package/src/__tests__/doctor.spec.ts +94 -0
- package/src/__tests__/dotenv-parse.spec.ts +105 -0
- package/src/__tests__/env/.env +2 -0
- package/src/__tests__/fixtures/default/.env +3 -0
- package/src/__tests__/fixtures/default/.env.development +1 -0
- package/src/__tests__/fixtures/default/.env.local +1 -0
- package/src/__tests__/fixtures/default/.env.pre +3 -0
- package/src/__tests__/fixtures/default/.env.production +1 -0
- package/src/__tests__/fixtures/default/.env.uat +5 -0
- package/src/__tests__/fixtures/default/.env.uat.local +1 -0
- package/src/__tests__/fixtures/default/babel.config.js +10 -0
- package/src/__tests__/fixtures/default/config/dev.js +9 -0
- package/src/__tests__/fixtures/default/config/index.js +84 -0
- package/src/__tests__/fixtures/default/config/prod.js +18 -0
- package/src/__tests__/fixtures/default/package.json +27 -0
- package/src/__tests__/fixtures/default/src/app.config.js +11 -0
- package/src/__tests__/fixtures/default/src/app.js +16 -0
- package/src/__tests__/fixtures/default/src/app.scss +0 -0
- package/src/__tests__/fixtures/default/src/index.html +19 -0
- package/src/__tests__/fixtures/default/src/pages/index/index.config.js +3 -0
- package/src/__tests__/fixtures/default/src/pages/index/index.jsx +22 -0
- package/src/__tests__/fixtures/default/src/pages/index/index.scss +0 -0
- package/src/__tests__/info.spec.ts +72 -0
- package/src/__tests__/inspect.spec.ts +160 -0
- package/src/__tests__/update.spec.ts +310 -0
- package/src/__tests__/utils/index.ts +54 -0
- package/src/cli.ts +240 -0
- package/src/commands/customCommand.ts +22 -0
- package/src/config/index.ts +7 -0
- package/src/config/manifest.default.json +33 -0
- package/src/config/packagesManagement.ts +20 -0
- package/src/config/rn-stylelint.json +4 -0
- package/src/config/tsconfig.json +22 -0
- package/src/create/constants.ts +1 -0
- package/src/create/creator.ts +37 -0
- package/src/create/fetchTemplate.ts +161 -0
- package/src/create/page.ts +325 -0
- package/src/create/plugin.ts +55 -0
- package/src/create/project.ts +539 -0
- package/src/doctor/index.ts +21 -0
- package/src/index.ts +24 -0
- package/src/presets/commands/build.ts +215 -0
- package/src/presets/commands/config.ts +86 -0
- package/src/presets/commands/create.ts +104 -0
- package/src/presets/commands/global-config.ts +140 -0
- package/src/presets/commands/help.ts +17 -0
- package/src/presets/commands/info.ts +81 -0
- package/src/presets/commands/init.ts +63 -0
- package/src/presets/commands/inspect.ts +137 -0
- package/src/presets/commands/update.ts +175 -0
- package/src/presets/constant/hooks.ts +14 -0
- package/src/presets/constant/index.ts +1 -0
- package/src/presets/files/generateFrameworkInfo.ts +30 -0
- package/src/presets/files/generateProjectConfig.ts +41 -0
- package/src/presets/files/writeFileToDist.ts +17 -0
- package/src/presets/hooks/build.ts +22 -0
- package/src/presets/hooks/create.ts +9 -0
- package/src/presets/index.ts +15 -0
- package/src/presets/platforms/plugin.ts +75 -0
- package/src/presets/platforms/rn.ts +125 -0
- package/src/util/appConfig.ts +32 -0
- package/src/util/createPage.ts +139 -0
- package/src/util/defineConfig.ts +28 -0
- package/src/util/index.ts +126 -0
- package/src/util/types.ts +81 -0
- package/templates/default/_editorconfig +12 -0
- package/templates/default/_env.development +2 -0
- package/templates/default/_env.production +1 -0
- package/templates/default/_env.test +1 -0
- package/templates/default/_gitignore +8 -0
- package/templates/default/babel.config.js +14 -0
- package/templates/default/config/dev.js +5 -0
- package/templates/default/config/index.js +61 -0
- package/templates/default/config/prod.js +5 -0
- package/templates/default/package.json.tmpl +52 -0
- package/templates/default/project.config.json +15 -0
- package/templates/default/src/app.config.js +11 -0
- package/templates/default/src/app.css +0 -0
- package/templates/default/src/app.js +15 -0
- package/templates/default/src/pages/index/index.config.js +3 -0
- package/templates/default/src/pages/index/index.css +0 -0
- package/templates/default/src/pages/index/index.jsx +15 -0
- package/templates/default/template_creator.js +61 -0
- package/templates/default/tsconfig.json +30 -0
- package/templates/default/types/global.d.ts +27 -0
- package/templates/global-config/index.json +4 -0
- package/templates/global-config/package.json +5 -0
- package/templates/plugin-compile/README.md +32 -0
- package/templates/plugin-compile/index.js +3 -0
- package/templates/plugin-compile/package.json.tmpl +43 -0
- package/templates/plugin-compile/src/index.ts +153 -0
- package/templates/plugin-compile/tsconfig.json +28 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
|
|
5
|
+
import { chalk } from '@spcsn/taro-helper';
|
|
6
|
+
import * as child_process from 'child_process';
|
|
7
|
+
|
|
8
|
+
import { printDevelopmentTip } from '../../util';
|
|
9
|
+
|
|
10
|
+
import type { IPluginContext } from '@spcsn/taro-service';
|
|
11
|
+
|
|
12
|
+
function checkReactNativeDependencies(packageInfo): boolean {
|
|
13
|
+
const packageNames = ['react', 'react-native', '@spcsn/taro-rn', '@spcsn/taro-rn-runner'];
|
|
14
|
+
const { dependencies, devDependencies } = packageInfo;
|
|
15
|
+
for (let i = 0; i < packageNames.length; i++) {
|
|
16
|
+
if (!dependencies[packageNames[i]] && !devDependencies[packageNames[i]]) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function makeSureReactNativeInstalled(workspaceRoot: string): Promise<void> {
|
|
24
|
+
return new Promise<void>((resolve, reject) => {
|
|
25
|
+
const packageInfo = JSON.parse(
|
|
26
|
+
fs.readFileSync(path.join(workspaceRoot, 'package.json'), {
|
|
27
|
+
encoding: 'utf8',
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
if (checkReactNativeDependencies(packageInfo)) {
|
|
32
|
+
resolve();
|
|
33
|
+
} else {
|
|
34
|
+
// 便于开发时切换版本
|
|
35
|
+
const devTag = process.env.DEVTAG || '';
|
|
36
|
+
console.log('Installing React-Native related packages:');
|
|
37
|
+
let packages = `react@^18.2.0 react-dom@^18.2.0 react-native@^0.73.1 @react-native/metro-config@^0.73.2 expo@~50.0.2 @tarojs/taro-rn${devTag} @tarojs/components-rn${devTag} @tarojs/rn-runner${devTag} @tarojs/rn-supporter${devTag} @tarojs/runtime-rn${devTag}`;
|
|
38
|
+
console.log(packages);
|
|
39
|
+
// windows下不加引号的话,package.json中添加的依赖不会自动带上^
|
|
40
|
+
packages = packages
|
|
41
|
+
.split(' ')
|
|
42
|
+
.map((str) => `"${str}"`)
|
|
43
|
+
.join(' ');
|
|
44
|
+
let installCmd = `npm install ${packages} --save`;
|
|
45
|
+
if (fs.existsSync(path.join(workspaceRoot, 'yarn.lock'))) {
|
|
46
|
+
installCmd = `yarn add ${packages} --force`;
|
|
47
|
+
}
|
|
48
|
+
if (fs.existsSync(path.join(workspaceRoot, 'pnpm-lock.yaml'))) {
|
|
49
|
+
installCmd = `pnpm add ${packages}`;
|
|
50
|
+
}
|
|
51
|
+
child_process.exec(installCmd, (error) => {
|
|
52
|
+
if (error) {
|
|
53
|
+
reject(error);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
console.log(chalk.green(`React-Native related packages have been installed successfully.${os.EOL}${os.EOL}`));
|
|
57
|
+
console.log(
|
|
58
|
+
`${chalk.yellow('ATTEHNTION')}: Package.json has been modified automatically, please submit it by yourself.${os.EOL}${os.EOL}`,
|
|
59
|
+
);
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default (ctx: IPluginContext) => {
|
|
67
|
+
ctx.registerPlatform({
|
|
68
|
+
name: 'rn',
|
|
69
|
+
useConfigName: 'rn',
|
|
70
|
+
async fn({ config }) {
|
|
71
|
+
const { appPath, nodeModulesPath } = ctx.paths;
|
|
72
|
+
const { npm } = ctx.helper;
|
|
73
|
+
const {
|
|
74
|
+
deviceType = 'android',
|
|
75
|
+
port,
|
|
76
|
+
resetCache,
|
|
77
|
+
publicPath,
|
|
78
|
+
bundleOutput,
|
|
79
|
+
sourcemapOutput,
|
|
80
|
+
sourceMapUrl,
|
|
81
|
+
sourcemapSourcesRoot,
|
|
82
|
+
assetsDest,
|
|
83
|
+
qr,
|
|
84
|
+
} = ctx.runOpts.options;
|
|
85
|
+
|
|
86
|
+
printDevelopmentTip('rn');
|
|
87
|
+
|
|
88
|
+
// 准备 rnRunner 参数
|
|
89
|
+
const rnRunnerOpts = {
|
|
90
|
+
...config,
|
|
91
|
+
nodeModulesPath,
|
|
92
|
+
deviceType,
|
|
93
|
+
port,
|
|
94
|
+
qr,
|
|
95
|
+
resetCache,
|
|
96
|
+
publicPath,
|
|
97
|
+
bundleOutput,
|
|
98
|
+
sourcemapOutput,
|
|
99
|
+
sourceMapUrl,
|
|
100
|
+
sourcemapSourcesRoot,
|
|
101
|
+
assetsDest,
|
|
102
|
+
buildAdapter: config.platform,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
if (!rnRunnerOpts.entry) {
|
|
106
|
+
rnRunnerOpts.entry = 'app';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
makeSureReactNativeInstalled(appPath).then(
|
|
110
|
+
async () => {
|
|
111
|
+
// build with metro
|
|
112
|
+
const rnRunner = await npm.getNpmPkg('@spcsn/taro-rn-runner', appPath);
|
|
113
|
+
await rnRunner(appPath, rnRunnerOpts);
|
|
114
|
+
},
|
|
115
|
+
(error) => {
|
|
116
|
+
console.log(chalk.red('Error when detecting React-Native packages:'));
|
|
117
|
+
console.log(error);
|
|
118
|
+
console.log(
|
|
119
|
+
`${chalk.greenBright('TIP')}: 1) Try to remove React-Native dependencies in package.json and shoot again; 2) Install the packages above manually.`,
|
|
120
|
+
);
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IPluginContext } from '@spcsn/taro-service';
|
|
2
|
+
import { isString } from '@spcsn/taro-shared';
|
|
3
|
+
import { AppConfig } from '@spcsn/taro';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 按需编译功能,只编译指定的页面或组件
|
|
7
|
+
* @param appConfig
|
|
8
|
+
* @param args
|
|
9
|
+
*/
|
|
10
|
+
export function extractCompileEntry(
|
|
11
|
+
appConfig: AppConfig,
|
|
12
|
+
args: { _: string[]; [key: string]: any },
|
|
13
|
+
ctx: IPluginContext,
|
|
14
|
+
): void {
|
|
15
|
+
const { chalk } = ctx.helper;
|
|
16
|
+
|
|
17
|
+
const extractType = isString(args.pages) ? 'pages' : isString(args.components) ? 'components' : '';
|
|
18
|
+
if (!extractType) return;
|
|
19
|
+
|
|
20
|
+
const entries = args[extractType]
|
|
21
|
+
.split(',')
|
|
22
|
+
.map((item) => item.trim())
|
|
23
|
+
.filter(Boolean);
|
|
24
|
+
if (!entries.length) {
|
|
25
|
+
console.log(chalk.yellow(`按需编译开启失败,请指定要编译的${extractType}`));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
appConfig[extractType] = entries;
|
|
30
|
+
appConfig.subPackages = [];
|
|
31
|
+
console.log(chalk.green(`已开启按需编译,仅编译以下${extractType}: ${appConfig[extractType]}`));
|
|
32
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { babelKit } from '@spcsn/taro-helper';
|
|
2
|
+
|
|
3
|
+
import { ConfigModificationState, ModifyCallback } from '../create/page';
|
|
4
|
+
|
|
5
|
+
import type { ArrayExpression, ExportDefaultDeclaration, ObjectExpression, ObjectProperty } from '@babel/types';
|
|
6
|
+
import type { NodePath } from 'babel__traverse';
|
|
7
|
+
|
|
8
|
+
const t = babelKit.types;
|
|
9
|
+
|
|
10
|
+
const generateNewSubPackageItem = (subPackage: string) => {
|
|
11
|
+
const pageObject = t.objectProperty(t.identifier('pages'), t.arrayExpression([]));
|
|
12
|
+
const subPkgRootObject = t.objectProperty(t.identifier('root'), t.stringLiteral(subPackage));
|
|
13
|
+
const subPkgItemObject = t.objectExpression([subPkgRootObject, pageObject]);
|
|
14
|
+
return subPkgItemObject;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const isValidSubPkgObject = (subPkgObject: ObjectExpression) => {
|
|
18
|
+
const properties = subPkgObject?.properties || {};
|
|
19
|
+
const rootProperty = properties.find(
|
|
20
|
+
(property) => (property as ObjectProperty).key && ((property as ObjectProperty).key as any)?.name === 'root',
|
|
21
|
+
) as ObjectProperty;
|
|
22
|
+
const pagesProperty = properties.find(
|
|
23
|
+
(property) => (property as ObjectProperty).key && ((property as ObjectProperty).key as any)?.name === 'pages',
|
|
24
|
+
) as ObjectProperty;
|
|
25
|
+
const rootPropertyValueType = rootProperty?.value?.type;
|
|
26
|
+
const pagesPropertyValueType = pagesProperty?.value?.type;
|
|
27
|
+
return rootPropertyValueType === 'StringLiteral' && pagesPropertyValueType === 'ArrayExpression';
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const addNewSubPackage = (node: ObjectExpression, page: string, subPackage: string): ConfigModificationState => {
|
|
31
|
+
let subPackages = node?.properties.find((node) => (node as any).key.name === 'subPackages') as ObjectProperty;
|
|
32
|
+
if (!subPackages) {
|
|
33
|
+
// config 文件不存在 subPackages 字段的情况,给该字段赋予默认值
|
|
34
|
+
const subPkgObject = t.objectProperty(t.identifier('subPackages'), t.arrayExpression([]));
|
|
35
|
+
subPackages = subPkgObject;
|
|
36
|
+
node?.properties.push(subPkgObject);
|
|
37
|
+
}
|
|
38
|
+
const value = subPackages?.value;
|
|
39
|
+
|
|
40
|
+
// 文件格式不对的情况
|
|
41
|
+
if (!value || value?.type !== 'ArrayExpression') return ConfigModificationState.Fail;
|
|
42
|
+
let targetSubPkgObject: ObjectExpression = value.elements.find((node) =>
|
|
43
|
+
(node as any)?.properties?.find((property) => (property as any)?.value?.value === subPackage),
|
|
44
|
+
) as ObjectExpression;
|
|
45
|
+
|
|
46
|
+
if (!targetSubPkgObject) {
|
|
47
|
+
// 不存在 当前分包配置对象的情况
|
|
48
|
+
const subPkgItemObject = generateNewSubPackageItem(subPackage);
|
|
49
|
+
targetSubPkgObject = subPkgItemObject;
|
|
50
|
+
value.elements.push(subPkgItemObject);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (targetSubPkgObject.type !== 'ObjectExpression' || !isValidSubPkgObject(targetSubPkgObject))
|
|
54
|
+
return ConfigModificationState.Fail;
|
|
55
|
+
const pagesProperty: ObjectProperty = targetSubPkgObject.properties.find(
|
|
56
|
+
(property) => (property as ObjectProperty).key && ((property as ObjectProperty).key as any)?.name === 'pages',
|
|
57
|
+
) as ObjectProperty;
|
|
58
|
+
const currentPages = (pagesProperty.value as ArrayExpression).elements;
|
|
59
|
+
const isPageExists = Boolean(currentPages.find((node) => (node as any).value === page));
|
|
60
|
+
|
|
61
|
+
if (isPageExists) return ConfigModificationState.NeedLess;
|
|
62
|
+
|
|
63
|
+
currentPages.push(t.stringLiteral(page));
|
|
64
|
+
return ConfigModificationState.Success;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const addNewPage = (node: ObjectExpression, page: string): ConfigModificationState => {
|
|
68
|
+
const pages = node?.properties.find((node) => (node as any).key.name === 'pages') as ObjectProperty;
|
|
69
|
+
if (!pages) return ConfigModificationState.Fail;
|
|
70
|
+
|
|
71
|
+
const value = pages?.value;
|
|
72
|
+
// 仅处理 pages 为数组字面量的情形
|
|
73
|
+
if (!value || value?.type !== 'ArrayExpression') return ConfigModificationState.Fail;
|
|
74
|
+
|
|
75
|
+
const isPageExists = Boolean(value.elements.find((node) => (node as any).value === page));
|
|
76
|
+
if (isPageExists) return ConfigModificationState.NeedLess;
|
|
77
|
+
|
|
78
|
+
const newArrayElement = t.stringLiteral(page);
|
|
79
|
+
value.elements.push(newArrayElement);
|
|
80
|
+
|
|
81
|
+
return ConfigModificationState.Success;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const modifyPages = (path: NodePath<ExportDefaultDeclaration>, newPageConfig, callback: ModifyCallback) => {
|
|
85
|
+
let state = ConfigModificationState.Fail;
|
|
86
|
+
const node = path.node.declaration as any;
|
|
87
|
+
// Case 1. `export default defineAppConfig({})` 这种情况
|
|
88
|
+
if (node.type === 'CallExpression' && node.callee.name === 'defineAppConfig') {
|
|
89
|
+
const configNode = node.arguments[0];
|
|
90
|
+
state = addNewPage(configNode, newPageConfig.page);
|
|
91
|
+
}
|
|
92
|
+
// Case 2. `export default {}` 这种情况
|
|
93
|
+
if (node.type === 'ObjectExpression') {
|
|
94
|
+
state = addNewPage(node, newPageConfig.page);
|
|
95
|
+
}
|
|
96
|
+
callback(state);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const modifySubPackages = (path: NodePath<ExportDefaultDeclaration>, newPageConfig, callback: ModifyCallback) => {
|
|
100
|
+
let state = ConfigModificationState.Fail;
|
|
101
|
+
const node = path.node.declaration as any;
|
|
102
|
+
// `export default defineAppConfig({})` 这种情况
|
|
103
|
+
if (node.type === 'CallExpression' && node.callee.name === 'defineAppConfig') {
|
|
104
|
+
const configNode = node.arguments[0];
|
|
105
|
+
state = addNewSubPackage(configNode, newPageConfig.page, newPageConfig.pkg);
|
|
106
|
+
}
|
|
107
|
+
// `export default {}` 这种情况
|
|
108
|
+
if (node.type === 'ObjectExpression') {
|
|
109
|
+
state = addNewSubPackage(node, newPageConfig.page, newPageConfig.pkg);
|
|
110
|
+
}
|
|
111
|
+
callback(state);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const generateNewPageConfig = (fullPagePath: string, subPkgRootPath = '') => {
|
|
115
|
+
const newPageConfig = {
|
|
116
|
+
pkg: '',
|
|
117
|
+
page: '',
|
|
118
|
+
};
|
|
119
|
+
if (subPkgRootPath) {
|
|
120
|
+
const processedSubPkg = `${subPkgRootPath}/`;
|
|
121
|
+
newPageConfig.pkg = processedSubPkg;
|
|
122
|
+
newPageConfig.page = fullPagePath.split(processedSubPkg)[1];
|
|
123
|
+
} else {
|
|
124
|
+
newPageConfig.page = fullPagePath;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return newPageConfig;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const modifyPagesOrSubPackages = (params: {
|
|
131
|
+
path: NodePath<ExportDefaultDeclaration>;
|
|
132
|
+
fullPagePath: string;
|
|
133
|
+
subPkgRootPath?: string;
|
|
134
|
+
callback: ModifyCallback;
|
|
135
|
+
}) => {
|
|
136
|
+
const { fullPagePath, subPkgRootPath, callback, path } = params;
|
|
137
|
+
const newPageConfig = generateNewPageConfig(fullPagePath, subPkgRootPath);
|
|
138
|
+
subPkgRootPath ? modifySubPackages(path, newPageConfig, callback) : modifyPages(path, newPageConfig, callback);
|
|
139
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IProjectConfig } from '@spcsn/taro/types/compile';
|
|
2
|
+
import type { CompilerTypes, CompilerWebpackTypes } from '@spcsn/taro/types/compile/compiler';
|
|
3
|
+
|
|
4
|
+
type WebpackMerge = (...configs: Array<object | null | undefined>) => object;
|
|
5
|
+
|
|
6
|
+
export interface ConfigEnv {
|
|
7
|
+
/** taro 当前执行的命令 */
|
|
8
|
+
command: string;
|
|
9
|
+
/** 当前模式 (mode) */
|
|
10
|
+
mode: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type UserConfigFn<T extends CompilerTypes = CompilerWebpackTypes> = (
|
|
14
|
+
merge: WebpackMerge,
|
|
15
|
+
env: ConfigEnv,
|
|
16
|
+
) => IProjectConfig<T> | Promise<IProjectConfig<T>>;
|
|
17
|
+
export type UserConfigExport<T extends CompilerTypes = CompilerWebpackTypes> =
|
|
18
|
+
| IProjectConfig<T>
|
|
19
|
+
| Promise<IProjectConfig<T>>
|
|
20
|
+
| UserConfigFn;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @since v3.6.9
|
|
24
|
+
* @warning 暂不支持 react native
|
|
25
|
+
*/
|
|
26
|
+
export function defineConfig<T extends CompilerTypes = CompilerWebpackTypes>(config: UserConfigExport<T>) {
|
|
27
|
+
return config;
|
|
28
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { chalk, fs, isWindows } from '@spcsn/taro-helper';
|
|
4
|
+
import { exec } from 'child_process';
|
|
5
|
+
|
|
6
|
+
export function getRootPath(): string {
|
|
7
|
+
return path.resolve(__dirname, '../../');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getPkgVersion(): string {
|
|
11
|
+
return require(path.join(getRootPath(), 'package.json')).version;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getPkgItemByKey(key: string) {
|
|
15
|
+
const packageMap = require(path.join(getRootPath(), 'package.json'));
|
|
16
|
+
if (Object.keys(packageMap).indexOf(key) === -1) {
|
|
17
|
+
return {};
|
|
18
|
+
} else {
|
|
19
|
+
return packageMap[key];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function printPkgVersion() {
|
|
24
|
+
const taroVersion = getPkgVersion();
|
|
25
|
+
console.log(`👽 Taro v${taroVersion}`);
|
|
26
|
+
console.log();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const getAllFilesInFolder = async (folder: string, filter: string[] = []): Promise<string[]> => {
|
|
30
|
+
let files: string[] = [];
|
|
31
|
+
const list = readDirWithFileTypes(folder);
|
|
32
|
+
|
|
33
|
+
await Promise.all(
|
|
34
|
+
list.map(async (item) => {
|
|
35
|
+
const itemPath = path.join(folder, item.name);
|
|
36
|
+
if (item.isDirectory) {
|
|
37
|
+
const _files = await getAllFilesInFolder(itemPath, filter);
|
|
38
|
+
files = [...files, ..._files];
|
|
39
|
+
} else if (item.isFile) {
|
|
40
|
+
if (!filter.find((rule) => rule === item.name)) files.push(itemPath);
|
|
41
|
+
}
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return files;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type TemplateSourceType = 'git' | 'url';
|
|
49
|
+
|
|
50
|
+
export function getTemplateSourceType(url: string): TemplateSourceType {
|
|
51
|
+
if (/^github:/.test(url) || /^gitlab:/.test(url) || /^direct:/.test(url)) {
|
|
52
|
+
return 'git';
|
|
53
|
+
} else {
|
|
54
|
+
return 'url';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface FileStat {
|
|
59
|
+
name: string;
|
|
60
|
+
isDirectory: boolean;
|
|
61
|
+
isFile: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function readDirWithFileTypes(folder: string): FileStat[] {
|
|
65
|
+
const list = fs.readdirSync(folder);
|
|
66
|
+
const res = list.map((name) => {
|
|
67
|
+
const stat = fs.statSync(path.join(folder, name));
|
|
68
|
+
return {
|
|
69
|
+
name,
|
|
70
|
+
isDirectory: stat.isDirectory(),
|
|
71
|
+
isFile: stat.isFile(),
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
return res;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function printDevelopmentTip(platform: string) {
|
|
78
|
+
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
|
|
79
|
+
let exampleCommand;
|
|
80
|
+
if (isWindows) {
|
|
81
|
+
exampleCommand = `$ set NODE_ENV=production && taro build --type ${platform} --watch`;
|
|
82
|
+
} else {
|
|
83
|
+
exampleCommand = `$ NODE_ENV=production taro build --type ${platform} --watch`;
|
|
84
|
+
}
|
|
85
|
+
console.log(
|
|
86
|
+
chalk.yellowBright(`Tips: 预览模式生成的文件较大,设置 NODE_ENV 为 production 可以开启压缩。
|
|
87
|
+
Example:
|
|
88
|
+
${exampleCommand}
|
|
89
|
+
`),
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function clearConsole() {
|
|
95
|
+
const readline = require('readline');
|
|
96
|
+
if (process.stdout.isTTY) {
|
|
97
|
+
const blank = '\n'.repeat(process.stdout.rows);
|
|
98
|
+
console.log(blank);
|
|
99
|
+
readline.cursorTo(process.stdout, 0, 0);
|
|
100
|
+
readline.clearScreenDown(process.stdout);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function execCommand(params: {
|
|
105
|
+
command: string;
|
|
106
|
+
successCallback?: (data: string) => void;
|
|
107
|
+
failCallback?: (data: string) => void;
|
|
108
|
+
}) {
|
|
109
|
+
const { command, successCallback, failCallback } = params;
|
|
110
|
+
const child = exec(command);
|
|
111
|
+
child.stdout!.on('data', function (data) {
|
|
112
|
+
successCallback?.(data);
|
|
113
|
+
});
|
|
114
|
+
child.stderr!.on('data', function (data) {
|
|
115
|
+
failCallback?.(data);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function getPkgNameByFilterVersion(pkgString: string) {
|
|
120
|
+
const versionFlagIndex = pkgString.lastIndexOf('@');
|
|
121
|
+
return versionFlagIndex === 0 ? pkgString : pkgString.slice(0, versionFlagIndex);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function isNil(value: any): value is null | undefined {
|
|
125
|
+
return value === null || value === undefined;
|
|
126
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export interface IInstallOptions {
|
|
2
|
+
dev: boolean;
|
|
3
|
+
peerDependencies?: boolean;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface INpmConfig {
|
|
7
|
+
dir: string;
|
|
8
|
+
name: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IResolvedCache {
|
|
12
|
+
[key: string]: {
|
|
13
|
+
main: string;
|
|
14
|
+
files: string[];
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface IPrettierConfig {
|
|
19
|
+
printWidth?: number;
|
|
20
|
+
tabWidth?: number;
|
|
21
|
+
useTabs?: boolean;
|
|
22
|
+
semi?: boolean;
|
|
23
|
+
singleQuote?: boolean;
|
|
24
|
+
jsxSingleQuote?: boolean;
|
|
25
|
+
trailingComma?: 'none' | 'es5' | 'all';
|
|
26
|
+
bracketSpacing?: boolean;
|
|
27
|
+
jsxBracketSameLine?: boolean;
|
|
28
|
+
arrowParens?: 'avoid' | 'always';
|
|
29
|
+
rangeStart?: number;
|
|
30
|
+
rangeEnd?: number;
|
|
31
|
+
parser?:
|
|
32
|
+
| 'babel'
|
|
33
|
+
| 'babylon'
|
|
34
|
+
| 'flow'
|
|
35
|
+
| 'typescript'
|
|
36
|
+
| 'css'
|
|
37
|
+
| 'scss'
|
|
38
|
+
| 'less'
|
|
39
|
+
| 'json'
|
|
40
|
+
| 'json5'
|
|
41
|
+
| 'json-stringify'
|
|
42
|
+
| 'graphql'
|
|
43
|
+
| 'markdown'
|
|
44
|
+
| 'mdx'
|
|
45
|
+
| 'html'
|
|
46
|
+
| 'vue'
|
|
47
|
+
| 'angular'
|
|
48
|
+
| 'yaml';
|
|
49
|
+
filepath?: string;
|
|
50
|
+
requirePragma?: boolean;
|
|
51
|
+
insertPragma?: boolean;
|
|
52
|
+
proseWrap?: 'always' | 'never' | 'preserve';
|
|
53
|
+
htmlWhitespaceSensitivity?: 'css' | 'strict' | 'ignore';
|
|
54
|
+
endOfLine?: 'auto' | 'lf' | 'crlf' | 'cr';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface IBuildOptions {
|
|
58
|
+
type?: string;
|
|
59
|
+
watch?: boolean;
|
|
60
|
+
platform?: string;
|
|
61
|
+
port?: number;
|
|
62
|
+
release?: boolean;
|
|
63
|
+
envHasBeenSet?: boolean;
|
|
64
|
+
page?: string;
|
|
65
|
+
component?: string;
|
|
66
|
+
uiIndex?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface IMiniAppBuildConfig {
|
|
70
|
+
adapter: string;
|
|
71
|
+
watch?: boolean;
|
|
72
|
+
envHasBeenSet?: boolean;
|
|
73
|
+
port?: number;
|
|
74
|
+
release?: boolean;
|
|
75
|
+
page?: string;
|
|
76
|
+
component?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface IOption {
|
|
80
|
+
[key: string]: any;
|
|
81
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# TARO_APP_ID="生产环境下的小程序 AppID"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# TARO_APP_ID="测试环境下的小程序 AppID"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// babel-preset-taro 更多选项和默认值:
|
|
2
|
+
// https://docs.taro.zone/docs/next/babel-config
|
|
3
|
+
module.exports = {
|
|
4
|
+
presets: [
|
|
5
|
+
['taro', {
|
|
6
|
+
framework: '{{ to_lower_case framework }}',
|
|
7
|
+
ts: {{ typescript }},
|
|
8
|
+
compiler: '{{ to_lower_case compiler }}',
|
|
9
|
+
{{#if buildEs5 }}
|
|
10
|
+
useBuiltIns: process.env.TARO_ENV === 'h5' ? 'usage' : false
|
|
11
|
+
{{/if}}
|
|
12
|
+
}]
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { defineConfig{{#if typescript }}, type UserConfigExport{{/if}} } from '@spcsn/taro-cli'
|
|
2
|
+
import devConfig from './dev'
|
|
3
|
+
import prodConfig from './prod'
|
|
4
|
+
|
|
5
|
+
// https://taro-docs.jd.com/docs/next/config#defineconfig-辅助函数
|
|
6
|
+
export default defineConfig{{#if typescript }}<'vite'>{{/if}}(async (merge, { command, mode }) => {
|
|
7
|
+
const baseConfig{{#if typescript }}: UserConfigExport<'vite'>{{/if}} = {
|
|
8
|
+
projectName: '{{ projectName }}',
|
|
9
|
+
date: '{{ date }}',
|
|
10
|
+
designWidth: 750,
|
|
11
|
+
deviceRatio: {
|
|
12
|
+
640: 2.34 / 2,
|
|
13
|
+
750: 1,
|
|
14
|
+
375: 2,
|
|
15
|
+
828: 1.81 / 2
|
|
16
|
+
},
|
|
17
|
+
sourceRoot: 'src',
|
|
18
|
+
outputRoot: 'dist',
|
|
19
|
+
plugins: [
|
|
20
|
+
"@spcsn/taro-plugin-generator"
|
|
21
|
+
],
|
|
22
|
+
defineConstants: {
|
|
23
|
+
},
|
|
24
|
+
copy: {
|
|
25
|
+
patterns: [
|
|
26
|
+
],
|
|
27
|
+
options: {
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
framework: 'react',
|
|
31
|
+
compiler: 'vite',
|
|
32
|
+
mini: {
|
|
33
|
+
postcss: {
|
|
34
|
+
pxtransform: {
|
|
35
|
+
enable: true,
|
|
36
|
+
config: {
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
cssModules: {
|
|
41
|
+
enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
|
|
42
|
+
config: {
|
|
43
|
+
namingPattern: 'module', // 转换模式,取值为 global/module
|
|
44
|
+
generateScopedName: '[name]__[local]___[hash:base64:5]'
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
{{#if buildEs5 }}
|
|
52
|
+
process.env.BROWSERSLIST_ENV = process.env.NODE_ENV
|
|
53
|
+
{{/if}}
|
|
54
|
+
|
|
55
|
+
if (process.env.NODE_ENV === 'development') {
|
|
56
|
+
// 本地开发构建配置(不混淆压缩)
|
|
57
|
+
return merge({}, baseConfig, devConfig)
|
|
58
|
+
}
|
|
59
|
+
// 生产构建配置(默认开启压缩混淆等)
|
|
60
|
+
return merge({}, baseConfig, prodConfig)
|
|
61
|
+
})
|