@vercel/build-utils 2.12.3-canary.28 → 2.12.3-canary.31
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/dist/convert-runtime-to-plugin.js +95 -24
- package/dist/index.js +95 -24
- package/package.json +2 -2
@@ -10,6 +10,36 @@ const glob_1 = __importDefault(require("./fs/glob"));
|
|
10
10
|
const normalize_path_1 = require("./fs/normalize-path");
|
11
11
|
const lambda_1 = require("./lambda");
|
12
12
|
const _1 = require(".");
|
13
|
+
// `.output` was already created by the Build Command, so we have
|
14
|
+
// to ensure its contents don't get bundled into the Lambda. Similarily,
|
15
|
+
// we don't want to bundle anything from `.vercel` either. Lastly,
|
16
|
+
// Builders/Runtimes didn't have `vercel.json` or `now.json`.
|
17
|
+
const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
|
18
|
+
const shouldIgnorePath = (file, ignoreFilter, ignoreFile) => {
|
19
|
+
const isNative = ignoredPaths.some(item => {
|
20
|
+
return file.startsWith(item);
|
21
|
+
});
|
22
|
+
if (!ignoreFile) {
|
23
|
+
return isNative;
|
24
|
+
}
|
25
|
+
return isNative || ignoreFilter(file);
|
26
|
+
};
|
27
|
+
const getSourceFiles = async (workPath, ignoreFilter) => {
|
28
|
+
const list = await glob_1.default('**', {
|
29
|
+
cwd: workPath,
|
30
|
+
});
|
31
|
+
// We're not passing this as an `ignore` filter to the `glob` function above,
|
32
|
+
// so that we can re-use exactly the same `getIgnoreFilter` method that the
|
33
|
+
// Build Step uses (literally the same code). Note that this exclusion only applies
|
34
|
+
// when deploying. Locally, another exclusion is needed, which is handled
|
35
|
+
// further below in the `convertRuntimeToPlugin` function.
|
36
|
+
for (const file in list) {
|
37
|
+
if (shouldIgnorePath(file, ignoreFilter, true)) {
|
38
|
+
delete list[file];
|
39
|
+
}
|
40
|
+
}
|
41
|
+
return list;
|
42
|
+
};
|
13
43
|
/**
|
14
44
|
* Convert legacy Runtime to a Plugin.
|
15
45
|
* @param buildRuntime - a legacy build() function from a Runtime
|
@@ -19,29 +49,25 @@ const _1 = require(".");
|
|
19
49
|
function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
20
50
|
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
21
51
|
return async function build({ workPath }) {
|
22
|
-
const opts = { cwd: workPath };
|
23
|
-
const files = await glob_1.default('**', opts);
|
24
|
-
// `.output` was already created by the Build Command, so we have
|
25
|
-
// to ensure its contents don't get bundled into the Lambda. Similarily,
|
26
|
-
// we don't want to bundle anything from `.vercel` either. Lastly,
|
27
|
-
// Builders/Runtimes didn't have `vercel.json` or `now.json`.
|
28
|
-
const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
|
29
52
|
// We also don't want to provide any files to Runtimes that were ignored
|
30
53
|
// through `.vercelignore` or `.nowignore`, because the Build Step does the same.
|
31
54
|
const ignoreFilter = await _1.getIgnoreFilter(workPath);
|
32
|
-
//
|
33
|
-
//
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
55
|
+
// Retrieve the files that are currently available on the File System,
|
56
|
+
// before the Legacy Runtime has even started to build.
|
57
|
+
const sourceFilesPreBuild = await getSourceFiles(workPath, ignoreFilter);
|
58
|
+
// Instead of doing another `glob` to get all the matching source files,
|
59
|
+
// we'll filter the list of existing files down to only the ones
|
60
|
+
// that are matching the entrypoint pattern, so we're first creating
|
61
|
+
// a clean new list to begin.
|
62
|
+
const entrypoints = Object.assign({}, sourceFilesPreBuild);
|
63
|
+
const entrypointMatch = new RegExp(`^api/.*${ext}$`);
|
64
|
+
// Up next, we'll strip out the files from the list of entrypoints
|
65
|
+
// that aren't actually considered entrypoints.
|
66
|
+
for (const file in entrypoints) {
|
67
|
+
if (!entrypointMatch.test(file)) {
|
68
|
+
delete entrypoints[file];
|
41
69
|
}
|
42
70
|
}
|
43
|
-
const entrypointPattern = `api/**/*${ext}`;
|
44
|
-
const entrypoints = await glob_1.default(entrypointPattern, opts);
|
45
71
|
const pages = {};
|
46
72
|
const pluginName = packageName.replace('vercel-plugin-', '');
|
47
73
|
const traceDir = path_1.join(workPath, `.output`, `inputs`,
|
@@ -53,7 +79,7 @@ function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
|
53
79
|
await fs_extra_1.default.ensureDir(traceDir);
|
54
80
|
for (const entrypoint of Object.keys(entrypoints)) {
|
55
81
|
const { output } = await buildRuntime({
|
56
|
-
files,
|
82
|
+
files: sourceFilesPreBuild,
|
57
83
|
entrypoint,
|
58
84
|
workPath,
|
59
85
|
config: {
|
@@ -63,8 +89,23 @@ function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
|
63
89
|
avoidTopLevelInstall: true,
|
64
90
|
},
|
65
91
|
});
|
92
|
+
// Legacy Runtimes tend to pollute the `workPath` with compiled results,
|
93
|
+
// because the `workPath` used to be a place that was a place where they could
|
94
|
+
// just put anything, but nowadays it's the working directory of the `vercel build`
|
95
|
+
// command, which is the place where the developer keeps their source files,
|
96
|
+
// so we don't want to pollute this space unnecessarily. That means we have to clean
|
97
|
+
// up files that were created by the build, which is done further below.
|
98
|
+
const sourceFilesAfterBuild = await getSourceFiles(workPath, ignoreFilter);
|
99
|
+
// Further down, we will need the filename of the Lambda handler
|
100
|
+
// for placing it inside `server/pages/api`, but because Legacy Runtimes
|
101
|
+
// don't expose the filename directly, we have to construct it
|
102
|
+
// from the handler name, and then find the matching file further below,
|
103
|
+
// because we don't yet know its extension here.
|
104
|
+
const handler = output.handler;
|
105
|
+
const handlerMethod = handler.split('.').reverse()[0];
|
106
|
+
const handlerFileName = handler.replace(`.${handlerMethod}`, '');
|
66
107
|
pages[entrypoint] = {
|
67
|
-
handler:
|
108
|
+
handler: handler,
|
68
109
|
runtime: output.runtime,
|
69
110
|
memory: output.memory,
|
70
111
|
maxDuration: output.maxDuration,
|
@@ -73,12 +114,42 @@ function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
|
73
114
|
};
|
74
115
|
// @ts-ignore This symbol is a private API
|
75
116
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
117
|
+
// When deploying, the `files` that are passed to the Legacy Runtimes already
|
118
|
+
// have certain files that are ignored stripped, but locally, that list of
|
119
|
+
// files isn't used by the Legacy Runtimes, so we need to apply the filters
|
120
|
+
// to the outputs that they are returning instead.
|
121
|
+
for (const file in lambdaFiles) {
|
122
|
+
if (shouldIgnorePath(file, ignoreFilter, false)) {
|
123
|
+
delete lambdaFiles[file];
|
124
|
+
}
|
125
|
+
}
|
126
|
+
const handlerFilePath = Object.keys(lambdaFiles).find(item => {
|
127
|
+
return path_1.parse(item).name === handlerFileName;
|
128
|
+
});
|
129
|
+
const handlerFileOrigin = lambdaFiles[handlerFilePath || ''].fsPath;
|
130
|
+
if (!handlerFileOrigin) {
|
131
|
+
throw new Error(`Could not find a handler file. Please ensure that the list of \`files\` defined for the returned \`Lambda\` contains a file with the name ${handlerFileName} (+ any extension).`);
|
132
|
+
}
|
76
133
|
const entry = path_1.join(workPath, '.output', 'server', 'pages', entrypoint);
|
77
134
|
await fs_extra_1.default.ensureDir(path_1.dirname(entry));
|
78
|
-
await linkOrCopy(
|
135
|
+
await linkOrCopy(handlerFileOrigin, entry);
|
136
|
+
const toRemove = [];
|
137
|
+
// You can find more details about this at the point where the
|
138
|
+
// `sourceFilesAfterBuild` is created originally.
|
139
|
+
for (const file in sourceFilesAfterBuild) {
|
140
|
+
if (!sourceFilesPreBuild[file]) {
|
141
|
+
const path = sourceFilesAfterBuild[file].fsPath;
|
142
|
+
toRemove.push(fs_extra_1.default.remove(path));
|
143
|
+
}
|
144
|
+
}
|
145
|
+
await Promise.all(toRemove);
|
79
146
|
const tracedFiles = [];
|
80
147
|
Object.entries(lambdaFiles).forEach(async ([relPath, file]) => {
|
81
148
|
const newPath = path_1.join(traceDir, relPath);
|
149
|
+
// The handler was already moved into position above.
|
150
|
+
if (relPath === handlerFilePath) {
|
151
|
+
return;
|
152
|
+
}
|
82
153
|
tracedFiles.push({ absolutePath: newPath, relativePath: relPath });
|
83
154
|
if (file.fsPath) {
|
84
155
|
await linkOrCopy(file.fsPath, newPath);
|
@@ -94,9 +165,9 @@ function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
|
94
165
|
const nft = path_1.join(workPath, '.output', 'server', 'pages', `${entrypoint}.nft.json`);
|
95
166
|
const json = JSON.stringify({
|
96
167
|
version: 1,
|
97
|
-
files: tracedFiles.map(
|
98
|
-
input: normalize_path_1.normalizePath(path_1.relative(nft,
|
99
|
-
output: normalize_path_1.normalizePath(
|
168
|
+
files: tracedFiles.map(file => ({
|
169
|
+
input: normalize_path_1.normalizePath(path_1.relative(nft, file.absolutePath)),
|
170
|
+
output: normalize_path_1.normalizePath(file.relativePath),
|
100
171
|
})),
|
101
172
|
});
|
102
173
|
await fs_extra_1.default.ensureDir(path_1.dirname(nft));
|
package/dist/index.js
CHANGED
@@ -32757,6 +32757,36 @@ const glob_1 = __importDefault(__webpack_require__(4240));
|
|
32757
32757
|
const normalize_path_1 = __webpack_require__(6261);
|
32758
32758
|
const lambda_1 = __webpack_require__(6721);
|
32759
32759
|
const _1 = __webpack_require__(2855);
|
32760
|
+
// `.output` was already created by the Build Command, so we have
|
32761
|
+
// to ensure its contents don't get bundled into the Lambda. Similarily,
|
32762
|
+
// we don't want to bundle anything from `.vercel` either. Lastly,
|
32763
|
+
// Builders/Runtimes didn't have `vercel.json` or `now.json`.
|
32764
|
+
const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
|
32765
|
+
const shouldIgnorePath = (file, ignoreFilter, ignoreFile) => {
|
32766
|
+
const isNative = ignoredPaths.some(item => {
|
32767
|
+
return file.startsWith(item);
|
32768
|
+
});
|
32769
|
+
if (!ignoreFile) {
|
32770
|
+
return isNative;
|
32771
|
+
}
|
32772
|
+
return isNative || ignoreFilter(file);
|
32773
|
+
};
|
32774
|
+
const getSourceFiles = async (workPath, ignoreFilter) => {
|
32775
|
+
const list = await glob_1.default('**', {
|
32776
|
+
cwd: workPath,
|
32777
|
+
});
|
32778
|
+
// We're not passing this as an `ignore` filter to the `glob` function above,
|
32779
|
+
// so that we can re-use exactly the same `getIgnoreFilter` method that the
|
32780
|
+
// Build Step uses (literally the same code). Note that this exclusion only applies
|
32781
|
+
// when deploying. Locally, another exclusion is needed, which is handled
|
32782
|
+
// further below in the `convertRuntimeToPlugin` function.
|
32783
|
+
for (const file in list) {
|
32784
|
+
if (shouldIgnorePath(file, ignoreFilter, true)) {
|
32785
|
+
delete list[file];
|
32786
|
+
}
|
32787
|
+
}
|
32788
|
+
return list;
|
32789
|
+
};
|
32760
32790
|
/**
|
32761
32791
|
* Convert legacy Runtime to a Plugin.
|
32762
32792
|
* @param buildRuntime - a legacy build() function from a Runtime
|
@@ -32766,29 +32796,25 @@ const _1 = __webpack_require__(2855);
|
|
32766
32796
|
function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
32767
32797
|
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
32768
32798
|
return async function build({ workPath }) {
|
32769
|
-
const opts = { cwd: workPath };
|
32770
|
-
const files = await glob_1.default('**', opts);
|
32771
|
-
// `.output` was already created by the Build Command, so we have
|
32772
|
-
// to ensure its contents don't get bundled into the Lambda. Similarily,
|
32773
|
-
// we don't want to bundle anything from `.vercel` either. Lastly,
|
32774
|
-
// Builders/Runtimes didn't have `vercel.json` or `now.json`.
|
32775
|
-
const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
|
32776
32799
|
// We also don't want to provide any files to Runtimes that were ignored
|
32777
32800
|
// through `.vercelignore` or `.nowignore`, because the Build Step does the same.
|
32778
32801
|
const ignoreFilter = await _1.getIgnoreFilter(workPath);
|
32779
|
-
//
|
32780
|
-
//
|
32781
|
-
|
32782
|
-
|
32783
|
-
|
32784
|
-
|
32785
|
-
|
32786
|
-
|
32787
|
-
|
32802
|
+
// Retrieve the files that are currently available on the File System,
|
32803
|
+
// before the Legacy Runtime has even started to build.
|
32804
|
+
const sourceFilesPreBuild = await getSourceFiles(workPath, ignoreFilter);
|
32805
|
+
// Instead of doing another `glob` to get all the matching source files,
|
32806
|
+
// we'll filter the list of existing files down to only the ones
|
32807
|
+
// that are matching the entrypoint pattern, so we're first creating
|
32808
|
+
// a clean new list to begin.
|
32809
|
+
const entrypoints = Object.assign({}, sourceFilesPreBuild);
|
32810
|
+
const entrypointMatch = new RegExp(`^api/.*${ext}$`);
|
32811
|
+
// Up next, we'll strip out the files from the list of entrypoints
|
32812
|
+
// that aren't actually considered entrypoints.
|
32813
|
+
for (const file in entrypoints) {
|
32814
|
+
if (!entrypointMatch.test(file)) {
|
32815
|
+
delete entrypoints[file];
|
32788
32816
|
}
|
32789
32817
|
}
|
32790
|
-
const entrypointPattern = `api/**/*${ext}`;
|
32791
|
-
const entrypoints = await glob_1.default(entrypointPattern, opts);
|
32792
32818
|
const pages = {};
|
32793
32819
|
const pluginName = packageName.replace('vercel-plugin-', '');
|
32794
32820
|
const traceDir = path_1.join(workPath, `.output`, `inputs`,
|
@@ -32800,7 +32826,7 @@ function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
|
32800
32826
|
await fs_extra_1.default.ensureDir(traceDir);
|
32801
32827
|
for (const entrypoint of Object.keys(entrypoints)) {
|
32802
32828
|
const { output } = await buildRuntime({
|
32803
|
-
files,
|
32829
|
+
files: sourceFilesPreBuild,
|
32804
32830
|
entrypoint,
|
32805
32831
|
workPath,
|
32806
32832
|
config: {
|
@@ -32810,8 +32836,23 @@ function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
|
32810
32836
|
avoidTopLevelInstall: true,
|
32811
32837
|
},
|
32812
32838
|
});
|
32839
|
+
// Legacy Runtimes tend to pollute the `workPath` with compiled results,
|
32840
|
+
// because the `workPath` used to be a place that was a place where they could
|
32841
|
+
// just put anything, but nowadays it's the working directory of the `vercel build`
|
32842
|
+
// command, which is the place where the developer keeps their source files,
|
32843
|
+
// so we don't want to pollute this space unnecessarily. That means we have to clean
|
32844
|
+
// up files that were created by the build, which is done further below.
|
32845
|
+
const sourceFilesAfterBuild = await getSourceFiles(workPath, ignoreFilter);
|
32846
|
+
// Further down, we will need the filename of the Lambda handler
|
32847
|
+
// for placing it inside `server/pages/api`, but because Legacy Runtimes
|
32848
|
+
// don't expose the filename directly, we have to construct it
|
32849
|
+
// from the handler name, and then find the matching file further below,
|
32850
|
+
// because we don't yet know its extension here.
|
32851
|
+
const handler = output.handler;
|
32852
|
+
const handlerMethod = handler.split('.').reverse()[0];
|
32853
|
+
const handlerFileName = handler.replace(`.${handlerMethod}`, '');
|
32813
32854
|
pages[entrypoint] = {
|
32814
|
-
handler:
|
32855
|
+
handler: handler,
|
32815
32856
|
runtime: output.runtime,
|
32816
32857
|
memory: output.memory,
|
32817
32858
|
maxDuration: output.maxDuration,
|
@@ -32820,12 +32861,42 @@ function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
|
32820
32861
|
};
|
32821
32862
|
// @ts-ignore This symbol is a private API
|
32822
32863
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
32864
|
+
// When deploying, the `files` that are passed to the Legacy Runtimes already
|
32865
|
+
// have certain files that are ignored stripped, but locally, that list of
|
32866
|
+
// files isn't used by the Legacy Runtimes, so we need to apply the filters
|
32867
|
+
// to the outputs that they are returning instead.
|
32868
|
+
for (const file in lambdaFiles) {
|
32869
|
+
if (shouldIgnorePath(file, ignoreFilter, false)) {
|
32870
|
+
delete lambdaFiles[file];
|
32871
|
+
}
|
32872
|
+
}
|
32873
|
+
const handlerFilePath = Object.keys(lambdaFiles).find(item => {
|
32874
|
+
return path_1.parse(item).name === handlerFileName;
|
32875
|
+
});
|
32876
|
+
const handlerFileOrigin = lambdaFiles[handlerFilePath || ''].fsPath;
|
32877
|
+
if (!handlerFileOrigin) {
|
32878
|
+
throw new Error(`Could not find a handler file. Please ensure that the list of \`files\` defined for the returned \`Lambda\` contains a file with the name ${handlerFileName} (+ any extension).`);
|
32879
|
+
}
|
32823
32880
|
const entry = path_1.join(workPath, '.output', 'server', 'pages', entrypoint);
|
32824
32881
|
await fs_extra_1.default.ensureDir(path_1.dirname(entry));
|
32825
|
-
await linkOrCopy(
|
32882
|
+
await linkOrCopy(handlerFileOrigin, entry);
|
32883
|
+
const toRemove = [];
|
32884
|
+
// You can find more details about this at the point where the
|
32885
|
+
// `sourceFilesAfterBuild` is created originally.
|
32886
|
+
for (const file in sourceFilesAfterBuild) {
|
32887
|
+
if (!sourceFilesPreBuild[file]) {
|
32888
|
+
const path = sourceFilesAfterBuild[file].fsPath;
|
32889
|
+
toRemove.push(fs_extra_1.default.remove(path));
|
32890
|
+
}
|
32891
|
+
}
|
32892
|
+
await Promise.all(toRemove);
|
32826
32893
|
const tracedFiles = [];
|
32827
32894
|
Object.entries(lambdaFiles).forEach(async ([relPath, file]) => {
|
32828
32895
|
const newPath = path_1.join(traceDir, relPath);
|
32896
|
+
// The handler was already moved into position above.
|
32897
|
+
if (relPath === handlerFilePath) {
|
32898
|
+
return;
|
32899
|
+
}
|
32829
32900
|
tracedFiles.push({ absolutePath: newPath, relativePath: relPath });
|
32830
32901
|
if (file.fsPath) {
|
32831
32902
|
await linkOrCopy(file.fsPath, newPath);
|
@@ -32841,9 +32912,9 @@ function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
|
32841
32912
|
const nft = path_1.join(workPath, '.output', 'server', 'pages', `${entrypoint}.nft.json`);
|
32842
32913
|
const json = JSON.stringify({
|
32843
32914
|
version: 1,
|
32844
|
-
files: tracedFiles.map(
|
32845
|
-
input: normalize_path_1.normalizePath(path_1.relative(nft,
|
32846
|
-
output: normalize_path_1.normalizePath(
|
32915
|
+
files: tracedFiles.map(file => ({
|
32916
|
+
input: normalize_path_1.normalizePath(path_1.relative(nft, file.absolutePath)),
|
32917
|
+
output: normalize_path_1.normalizePath(file.relativePath),
|
32847
32918
|
})),
|
32848
32919
|
});
|
32849
32920
|
await fs_extra_1.default.ensureDir(path_1.dirname(nft));
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vercel/build-utils",
|
3
|
-
"version": "2.12.3-canary.
|
3
|
+
"version": "2.12.3-canary.31",
|
4
4
|
"license": "MIT",
|
5
5
|
"main": "./dist/index.js",
|
6
6
|
"types": "./dist/index.d.js",
|
@@ -49,5 +49,5 @@
|
|
49
49
|
"typescript": "4.3.4",
|
50
50
|
"yazl": "2.4.3"
|
51
51
|
},
|
52
|
-
"gitHead": "
|
52
|
+
"gitHead": "6f4a1b527ba01973490e1fb2e4c48ccb2841cd86"
|
53
53
|
}
|