sugar-scripts 0.2.0-beta.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/CHANGELOG.md +26 -0
- package/README.md +64 -0
- package/bin/cli-ts.js +3 -0
- package/bin/cli.js +3 -0
- package/package.json +53 -0
- package/src/app-utils/index.ts +1 -0
- package/src/app-utils/static.ts +42 -0
- package/src/commander/index.ts +95 -0
- package/src/configs/babel.server.config.ts +42 -0
- package/src/configs/babel.static.config.ts +43 -0
- package/src/constants/index.ts +5 -0
- package/src/core/build.ts +98 -0
- package/src/core/cache.ts +15 -0
- package/src/core/entry.ts +189 -0
- package/src/core/info.ts +5 -0
- package/src/core/init-running-context.ts +27 -0
- package/src/core/run-application.ts +12 -0
- package/src/core/running-context.ts +92 -0
- package/src/custom-config.type.ts +66 -0
- package/src/index.ts +7 -0
- package/src/shared/file-helpers.ts +192 -0
- package/src/typings.d.ts +8 -0
- package/src/webpack/auto-entries.ts +5 -0
- package/src/webpack/dll-dependencies-manifest-plugin.ts +115 -0
- package/src/webpack/load-manifest.ts +73 -0
- package/src/webpack/run-webpack.ts +22 -0
- package/src/webpack/webpack.browser.ts +107 -0
- package/src/webpack/webpack.common.ts +146 -0
- package/src/webpack/webpack.server.ts +100 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findProject,
|
|
3
|
+
findPackage
|
|
4
|
+
} from '../shared/file-helpers';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
SugarScriptsContext
|
|
8
|
+
} from './running-context';
|
|
9
|
+
|
|
10
|
+
export const initRunningContext = async (dir: string) => {
|
|
11
|
+
const {
|
|
12
|
+
root,
|
|
13
|
+
packageJson,
|
|
14
|
+
packageConfig
|
|
15
|
+
} = await findPackage(dir);
|
|
16
|
+
const { projectRoot, projectConfig } = await findProject(root);
|
|
17
|
+
if (!packageConfig || !projectConfig) {
|
|
18
|
+
throw new Error('')
|
|
19
|
+
}
|
|
20
|
+
return new SugarScriptsContext({
|
|
21
|
+
root,
|
|
22
|
+
packageName: packageJson.name,
|
|
23
|
+
packageConfig,
|
|
24
|
+
projectRoot,
|
|
25
|
+
projectConfig
|
|
26
|
+
})
|
|
27
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
type BuildEntry = { [key: string]: string|string[] };
|
|
5
|
+
|
|
6
|
+
interface PackageConfig {
|
|
7
|
+
browser?: {
|
|
8
|
+
/**
|
|
9
|
+
* 是否构建dll用的输出
|
|
10
|
+
*/
|
|
11
|
+
dll?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* 输出目录
|
|
14
|
+
*/
|
|
15
|
+
output: string;
|
|
16
|
+
/**
|
|
17
|
+
* controller/index
|
|
18
|
+
*/
|
|
19
|
+
input?: string;
|
|
20
|
+
entry?: BuildEntry
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
server?: {
|
|
24
|
+
dll?: boolean;
|
|
25
|
+
output: string;
|
|
26
|
+
entry: string;
|
|
27
|
+
render?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface ProjectConfig {
|
|
32
|
+
cacheDir: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getHashFromRoot (
|
|
36
|
+
root: string
|
|
37
|
+
) {
|
|
38
|
+
const hash = createHash('md5');
|
|
39
|
+
hash.update(root);
|
|
40
|
+
return `s_${hash.digest('hex')}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class SugarScriptsContext {
|
|
44
|
+
root: string;
|
|
45
|
+
rootHash: string;
|
|
46
|
+
packageName: string;
|
|
47
|
+
packageConfig: PackageConfig;
|
|
48
|
+
projectRoot: string;
|
|
49
|
+
projectConfig: ProjectConfig;
|
|
50
|
+
|
|
51
|
+
constructor (
|
|
52
|
+
{
|
|
53
|
+
root,
|
|
54
|
+
packageName,
|
|
55
|
+
packageConfig,
|
|
56
|
+
projectRoot,
|
|
57
|
+
projectConfig
|
|
58
|
+
}: {
|
|
59
|
+
root: string;
|
|
60
|
+
packageName: string;
|
|
61
|
+
packageConfig: PackageConfig;
|
|
62
|
+
projectRoot: string;
|
|
63
|
+
projectConfig: ProjectConfig;
|
|
64
|
+
}
|
|
65
|
+
) {
|
|
66
|
+
this.root = root;
|
|
67
|
+
this.packageName = packageName;
|
|
68
|
+
this.packageConfig = packageConfig;
|
|
69
|
+
this.projectRoot = projectRoot;
|
|
70
|
+
this.projectConfig = projectConfig;
|
|
71
|
+
this.rootHash = getHashFromRoot(root);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
serverEntryName = 'main';
|
|
75
|
+
|
|
76
|
+
getStartFilePath () {
|
|
77
|
+
if (this.packageConfig.server) {
|
|
78
|
+
return path.resolve(
|
|
79
|
+
this.root,
|
|
80
|
+
this.packageConfig.server.output,
|
|
81
|
+
this.serverEntryName
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
getCacheDir () {
|
|
87
|
+
return path.resolve(
|
|
88
|
+
this.projectRoot,
|
|
89
|
+
this.projectConfig.cacheDir
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ControllerContext
|
|
3
|
+
} from 'sugar-server';
|
|
4
|
+
import type WebpackChainConfig from 'webpack-chain';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
SugarScriptsContext
|
|
8
|
+
} from './core/running-context'
|
|
9
|
+
|
|
10
|
+
export namespace SugarScriptsProject {
|
|
11
|
+
export type BrowserWebpackConfig = CustomWebpackConfig;
|
|
12
|
+
|
|
13
|
+
export type ServerWebpackConfig = CustomWebpackConfig;
|
|
14
|
+
|
|
15
|
+
export interface PackageConfig {
|
|
16
|
+
browser?: {
|
|
17
|
+
/**
|
|
18
|
+
* 是否构建dll用的输出
|
|
19
|
+
*/
|
|
20
|
+
dll?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* 输出目录
|
|
23
|
+
*/
|
|
24
|
+
output: string;
|
|
25
|
+
/**
|
|
26
|
+
* controller/index
|
|
27
|
+
*/
|
|
28
|
+
input?: string;
|
|
29
|
+
entry?: BuildEntry
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
server?: {
|
|
33
|
+
dll?: boolean;
|
|
34
|
+
output: string;
|
|
35
|
+
entry: string;
|
|
36
|
+
render?: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ProjectConfig {
|
|
41
|
+
cacheDir: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
export interface CustomRender<C = any> {
|
|
46
|
+
(
|
|
47
|
+
ctx: ControllerContext,
|
|
48
|
+
entries: string[] | {[key: string]: string[]},
|
|
49
|
+
custom: C
|
|
50
|
+
): string
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type BuildEntry = { [key: string]: string|string[] };
|
|
55
|
+
|
|
56
|
+
export type CustomWebpackConfig = (
|
|
57
|
+
webpackChainConfig: WebpackChainConfig,
|
|
58
|
+
context: SugarScriptsContext
|
|
59
|
+
) => void;
|
|
60
|
+
|
|
61
|
+
export type CustomRender<C = any> = (
|
|
62
|
+
ctx: ControllerContext,
|
|
63
|
+
entries: string[] | {[key: string]: string[]},
|
|
64
|
+
custom: C
|
|
65
|
+
) => string;
|
|
66
|
+
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
SUGAR_PACKAGE_CONFIG_FILENAME,
|
|
6
|
+
SUGAR_PROJECT_CONFIG_FILENAME
|
|
7
|
+
} from '../constants';
|
|
8
|
+
import {
|
|
9
|
+
SugarScriptsProject
|
|
10
|
+
} from '../custom-config.type';
|
|
11
|
+
// nodejs v10 支持
|
|
12
|
+
// nodejs v14 才开始支持require('fs/promises')
|
|
13
|
+
const fsPromises = fs.promises;
|
|
14
|
+
|
|
15
|
+
export const searchFiles = async (
|
|
16
|
+
dir: string,
|
|
17
|
+
fileCheck: string | ((filePath: string) => boolean),
|
|
18
|
+
exclude?: string
|
|
19
|
+
) => {
|
|
20
|
+
try {
|
|
21
|
+
await fsPromises.access(dir)
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const files = await fsPromises.readdir(dir);
|
|
26
|
+
let currentFiles: string[] = [];
|
|
27
|
+
|
|
28
|
+
await Promise.all(
|
|
29
|
+
files.map(async (filename) => {
|
|
30
|
+
if (exclude === filename) return;
|
|
31
|
+
const fileOrDir = path.join(dir, filename);
|
|
32
|
+
const stats = await fsPromises.stat(fileOrDir);
|
|
33
|
+
if (stats.isFile()) {
|
|
34
|
+
if (typeof fileCheck === 'string') {
|
|
35
|
+
if (filename === fileCheck) {
|
|
36
|
+
currentFiles.push(fileOrDir)
|
|
37
|
+
}
|
|
38
|
+
} else if (fileCheck(fileOrDir)) {
|
|
39
|
+
currentFiles.push(fileOrDir)
|
|
40
|
+
}
|
|
41
|
+
} else if (stats.isDirectory()) {
|
|
42
|
+
const childCurrentFiles = await searchFiles(fileOrDir, fileCheck);
|
|
43
|
+
currentFiles = currentFiles.concat(childCurrentFiles);
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
)
|
|
47
|
+
return currentFiles;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const findSiblingFile = async (
|
|
51
|
+
currentFilePath: string,
|
|
52
|
+
searchFileName: string
|
|
53
|
+
) => {
|
|
54
|
+
const dir = path.dirname(currentFilePath);
|
|
55
|
+
const searchFilePath = path.join(dir, searchFileName);
|
|
56
|
+
|
|
57
|
+
const searchFileStat = await fsPromises.stat(searchFilePath);
|
|
58
|
+
if (searchFileStat.isFile()) {
|
|
59
|
+
return searchFilePath;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const findParentFile = async (
|
|
66
|
+
currentFilePath: string,
|
|
67
|
+
searchFileName: string
|
|
68
|
+
) => {
|
|
69
|
+
const dir = path.resolve(
|
|
70
|
+
path.dirname(currentFilePath),
|
|
71
|
+
'../'
|
|
72
|
+
);
|
|
73
|
+
const searchFilePath = path.join(dir, searchFileName);
|
|
74
|
+
|
|
75
|
+
const searchFileStat = await fsPromises.stat(searchFilePath);
|
|
76
|
+
if (searchFileStat.isFile()) {
|
|
77
|
+
return searchFilePath;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const loadJSON = async (filePath: string) => {
|
|
84
|
+
try {
|
|
85
|
+
const contentBuffer = await fsPromises.readFile(filePath);
|
|
86
|
+
const content = contentBuffer.toString();
|
|
87
|
+
|
|
88
|
+
return JSON.parse(content);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
return {};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const writeFileSync = (
|
|
95
|
+
filePath: string,
|
|
96
|
+
data: string | NodeJS.ArrayBufferView
|
|
97
|
+
) => {
|
|
98
|
+
const dir = path.dirname(filePath);
|
|
99
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
100
|
+
fs.writeFileSync(
|
|
101
|
+
filePath,
|
|
102
|
+
data
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const findPackage = async (dir: string): Promise<{
|
|
107
|
+
root: string;
|
|
108
|
+
packageJson: any;
|
|
109
|
+
packageConfig: SugarScriptsProject.PackageConfig | null;
|
|
110
|
+
}> => {
|
|
111
|
+
const packagePath = path.resolve(dir, 'package.json');
|
|
112
|
+
|
|
113
|
+
let existed = true;
|
|
114
|
+
try {
|
|
115
|
+
await fsPromises.access(packagePath, fs.constants.F_OK);
|
|
116
|
+
} catch (e) {
|
|
117
|
+
existed = false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
let packageConfig = null;
|
|
121
|
+
try {
|
|
122
|
+
packageConfig = require(
|
|
123
|
+
path.resolve(dir, SUGAR_PACKAGE_CONFIG_FILENAME)
|
|
124
|
+
).packageConfig;
|
|
125
|
+
} catch (e) {}
|
|
126
|
+
|
|
127
|
+
if (existed) {
|
|
128
|
+
return {
|
|
129
|
+
root: dir,
|
|
130
|
+
packageJson: require(
|
|
131
|
+
packagePath
|
|
132
|
+
),
|
|
133
|
+
packageConfig
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (dir === '/') {
|
|
138
|
+
throw new Error('not found package.json');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return findPackage(
|
|
142
|
+
path.resolve(dir, '../')
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export const findProject = async (dir: string): Promise<{
|
|
147
|
+
projectRoot: string,
|
|
148
|
+
projectConfig: SugarScriptsProject.ProjectConfig
|
|
149
|
+
}> => {
|
|
150
|
+
const projectPath = path.resolve(dir, SUGAR_PROJECT_CONFIG_FILENAME);
|
|
151
|
+
|
|
152
|
+
let projectConfig = null;
|
|
153
|
+
try {
|
|
154
|
+
projectConfig = require(projectPath).projectConfig;
|
|
155
|
+
} catch (e) {}
|
|
156
|
+
|
|
157
|
+
if (dir === '/') {
|
|
158
|
+
throw new Error('not found sugar.project');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (projectConfig) {
|
|
162
|
+
return {
|
|
163
|
+
projectRoot: dir,
|
|
164
|
+
projectConfig
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return findProject(
|
|
169
|
+
path.resolve(dir, '../')
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export const rm = async (filePath: string) => {
|
|
174
|
+
const stat = await fsPromises.stat(filePath);
|
|
175
|
+
if (
|
|
176
|
+
stat.isFile()
|
|
177
|
+
|| stat.isSymbolicLink()
|
|
178
|
+
) {
|
|
179
|
+
await fsPromises.unlink(filePath);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (stat.isDirectory()) {
|
|
183
|
+
const childFilePaths = await fsPromises.readdir(filePath);
|
|
184
|
+
await Promise.all(
|
|
185
|
+
childFilePaths.map((childFilePath) => (
|
|
186
|
+
rm(path.resolve(filePath, childFilePath))
|
|
187
|
+
))
|
|
188
|
+
);
|
|
189
|
+
await fsPromises.rmdir(filePath);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
package/src/typings.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import webpack from 'webpack';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
writeFileSync
|
|
5
|
+
} from '../shared/file-helpers';
|
|
6
|
+
|
|
7
|
+
export interface DllDependenciesManifestPluginOptions {
|
|
8
|
+
dllAssets: {
|
|
9
|
+
[dllName: string]: string[];
|
|
10
|
+
}
|
|
11
|
+
fileName: string,
|
|
12
|
+
generate: (entries: {
|
|
13
|
+
[entry: string]: string[]
|
|
14
|
+
}) => any
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const PLUGIN_NAME = 'DllDependenciesManifestPlugin';
|
|
18
|
+
|
|
19
|
+
export class DllDependenciesManifestPlugin {
|
|
20
|
+
options: DllDependenciesManifestPluginOptions;
|
|
21
|
+
constructor (options: DllDependenciesManifestPluginOptions) {
|
|
22
|
+
this.options = options;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
apply (compiler: webpack.Compiler) {
|
|
26
|
+
const logger = compiler.getInfrastructureLogger(PLUGIN_NAME);
|
|
27
|
+
|
|
28
|
+
compiler.hooks.done.tap(
|
|
29
|
+
PLUGIN_NAME,
|
|
30
|
+
(stats) => {
|
|
31
|
+
var data = stats.toJson({
|
|
32
|
+
all: false,
|
|
33
|
+
entrypoints: true,
|
|
34
|
+
chunks: true,
|
|
35
|
+
chunkModules: true,
|
|
36
|
+
// nestedModules: true,
|
|
37
|
+
dependentModules: true,
|
|
38
|
+
moduleAssets: true,
|
|
39
|
+
assets: true,
|
|
40
|
+
modules: true,
|
|
41
|
+
// moduleTrace: true,
|
|
42
|
+
// reasons: true,
|
|
43
|
+
chunkRelations: true,
|
|
44
|
+
ids: true,
|
|
45
|
+
publicPath: true
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const publicPath = data.publicPath;
|
|
49
|
+
const entries: {
|
|
50
|
+
[entry: string]: string[]
|
|
51
|
+
} = data.entrypoints
|
|
52
|
+
? Object.keys(data.entrypoints).reduce((entries, entryKey) => {
|
|
53
|
+
entries[entryKey] = [];
|
|
54
|
+
const entryAssets = data.entrypoints![entryKey].assets;
|
|
55
|
+
if (entryAssets) {
|
|
56
|
+
const normalizePath = (path: string): string => {
|
|
57
|
+
if (!path.endsWith('/')) {
|
|
58
|
+
return `${path}/`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return path;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
entries[entryKey] = entries[entryKey].concat(
|
|
65
|
+
entryAssets.map(({ name }) => (
|
|
66
|
+
publicPath ? normalizePath(publicPath) + name : name
|
|
67
|
+
))
|
|
68
|
+
)
|
|
69
|
+
};
|
|
70
|
+
return entries;
|
|
71
|
+
}, {} as {
|
|
72
|
+
[entry: string]: string[]
|
|
73
|
+
})
|
|
74
|
+
: {};
|
|
75
|
+
|
|
76
|
+
data.chunks?.forEach((chunk) => {
|
|
77
|
+
if (chunk.entry) {
|
|
78
|
+
let depDllAssets: string[] = [];
|
|
79
|
+
chunk.modules?.forEach((module) => {
|
|
80
|
+
if (
|
|
81
|
+
module.type !== 'module'
|
|
82
|
+
|| !module.identifier
|
|
83
|
+
) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const dllNameResult = /dll-reference (.+)$/.exec(module.identifier)
|
|
87
|
+
if (!dllNameResult) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const dllName = dllNameResult[1];
|
|
91
|
+
depDllAssets = depDllAssets.concat(
|
|
92
|
+
this.options.dllAssets[dllName]
|
|
93
|
+
)
|
|
94
|
+
})
|
|
95
|
+
if (entries[chunk.id as any]) {
|
|
96
|
+
entries[chunk.id as any] = depDllAssets.concat(entries[chunk.id as any])
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
// 去重复
|
|
102
|
+
Object.keys(entries).forEach((key) => {
|
|
103
|
+
entries[key] = Array.from(new Set(entries[key]))
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
const manifest = this.options.generate(entries);
|
|
107
|
+
|
|
108
|
+
writeFileSync(
|
|
109
|
+
this.options.fileName,
|
|
110
|
+
JSON.stringify(manifest, null, 2)
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
searchFiles,
|
|
5
|
+
findParentFile,
|
|
6
|
+
loadJSON
|
|
7
|
+
} from '../shared/file-helpers';
|
|
8
|
+
|
|
9
|
+
export async function loadAllDllModulesManifest (
|
|
10
|
+
dir: string,
|
|
11
|
+
exclude?: string
|
|
12
|
+
): Promise<{
|
|
13
|
+
context: string;
|
|
14
|
+
manifest: {
|
|
15
|
+
name: string;
|
|
16
|
+
content: any;
|
|
17
|
+
};
|
|
18
|
+
moduleName: string;
|
|
19
|
+
name: string;
|
|
20
|
+
assets: string[]
|
|
21
|
+
}[]> {
|
|
22
|
+
const moduleFilePaths = await searchFiles(
|
|
23
|
+
dir,
|
|
24
|
+
'dll.modules.manifest.json',
|
|
25
|
+
exclude
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const modules = await Promise.all(
|
|
29
|
+
moduleFilePaths.map(async (moduleFilePath) => {
|
|
30
|
+
const moduleConfigFilePath = await findParentFile(
|
|
31
|
+
moduleFilePath,
|
|
32
|
+
'manifest.json'
|
|
33
|
+
);
|
|
34
|
+
if (!moduleConfigFilePath) {
|
|
35
|
+
throw new Error(`not find manifest.json for ${moduleFilePath}`)
|
|
36
|
+
}
|
|
37
|
+
const moduleConfig = await loadJSON(moduleConfigFilePath);
|
|
38
|
+
const module = await loadJSON(moduleFilePath);
|
|
39
|
+
const name = module.name.split('_sn_').slice(1).join('_sn_');
|
|
40
|
+
return {
|
|
41
|
+
context: moduleConfig.context,
|
|
42
|
+
manifest: module,
|
|
43
|
+
moduleName: module.name,
|
|
44
|
+
name,
|
|
45
|
+
assets: moduleConfig.entries[name]
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return modules.filter((module) => !!module) as {
|
|
51
|
+
context: string;
|
|
52
|
+
manifest: {
|
|
53
|
+
name: string;
|
|
54
|
+
content: any;
|
|
55
|
+
};
|
|
56
|
+
moduleName: string;
|
|
57
|
+
name: string;
|
|
58
|
+
assets: string[]
|
|
59
|
+
}[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function loadBaseManifest (
|
|
63
|
+
dir: string,
|
|
64
|
+
rootHash: string
|
|
65
|
+
) {
|
|
66
|
+
return loadJSON(
|
|
67
|
+
path.resolve(
|
|
68
|
+
dir,
|
|
69
|
+
rootHash,
|
|
70
|
+
'./manifest.json'
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import webpack from 'webpack';
|
|
2
|
+
import WebpackChainConfig from 'webpack-chain';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export const runWebpack = (
|
|
6
|
+
chainConfig: WebpackChainConfig
|
|
7
|
+
) => {
|
|
8
|
+
const compiler = webpack(
|
|
9
|
+
chainConfig.toConfig()
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
compiler.run((err, stats) => {
|
|
14
|
+
if (err || stats && stats.hasErrors()) {
|
|
15
|
+
reject(err || stats?.toString())
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
console.log(stats?.toString())
|
|
19
|
+
resolve(stats)
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
}
|