Skip to content

Commit

Permalink
fix: improve pnp support, specially with ts
Browse files Browse the repository at this point in the history
  • Loading branch information
sergioramos committed Sep 22, 2020
1 parent 54cb6ce commit 20a1c5e
Show file tree
Hide file tree
Showing 13 changed files with 383 additions and 21 deletions.
187 changes: 176 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const SortBy = require('lodash.sortby');
const ToPairs = require('lodash.topairs');
const { writeSync } = require('tempy');
const Uniq = require('lodash.uniq');
const pkgUp = require('pkg-up');

const zipService = require('serverless/lib/plugins/package/lib/zipService');
const packageService = require('serverless/lib/plugins/package/lib/packageService');
Expand All @@ -34,6 +35,29 @@ const NODE_BUILTINS = [
'sys',
];

if ('pnp' in process.versions) {
try {
const {
buildNodeModulesTree,
buildLocatorMap,
} = require('@yarnpkg/pnpify');

// eslint-disable-next-line no-var, block-scoped-var
var pnp = require('pnpapi');
// eslint-disable-next-line no-var, block-scoped-var
var locatorMap = buildLocatorMap(
// eslint-disable-next-line block-scoped-var
buildNodeModulesTree(pnp, { pnpifyFs: false }),
);
} catch (err) {
console.error(err);
// eslint-disable-next-line no-var, no-redeclare
var locatorMap;
// eslint-disable-next-line no-var, no-redeclare
var pnp;
}
}

try {
// eslint-disable-next-line no-var
var {
Expand Down Expand Up @@ -225,13 +249,14 @@ module.exports = class {
statAsync(pathname),
]);

const ext = extname(pathname);
const filePath = relative(
this.servicePath,
resolve(
this.servicePath,
dirname(pathname),
basename(pathname, extname(pathname)),
).concat('.js'),
basename(pathname, ext),
).concat(['.ts', '.tsx'].includes(ext) ? '.js' : ext),
);

return {
Expand All @@ -258,6 +283,73 @@ module.exports = class {
this.serverless.utils.writeFileDir(artifactFilePath);
const output = fs.createWriteStream(artifactFilePath);

const inferNodeModulesPath = ({ filePath, name, key }) => {
const filePathParts = filePath.split(sep);
const nameParts = name.split(sep);

const nameIndex = nameParts.findIndex((namePart, nameIndex) => {
return filePathParts.find((filePathPart, filePathIndex) => {
return (
filePathPart === namePart &&
nameParts[nameIndex + 1] === filePathParts[filePathIndex + 1]
);
});
});

const sharedSize = /^@/.test(key) ? 3 : 2;

return join(
filePath,
nameParts.slice(nameIndex + sharedSize, nameParts.length).join(sep),
);
};

const revertPnp = ({ filePath }) => {
// eslint-disable-next-line block-scoped-var
if (!locatorMap) {
return;
}

try {
const name = filePath.slice(prefix ? `${prefix}${sep}`.length : 0);

// eslint-disable-next-line block-scoped-var
const { name: key, reference } = pnp.findPackageLocator(name);
// eslint-disable-next-line block-scoped-var
const { locations, target } = locatorMap.get(`${key}@${reference}`);
const isSymlink = !/\.yarn\//.test(name);

const fullTarget = isSymlink ? target : join(this.servicePath, name);
const stat = lstatSync(fullTarget);
const data = isSymlink ? Buffer.from('') : readFileSync(fullTarget);

return locations.map((source) => {
if (isSymlink) {
return {
stat,
filePath: relative(this.servicePath, source),
data,
type: 'symlink',
linkname: relative(dirname(source), target),
};
}

return {
data,
stat,
filePath: inferNodeModulesPath({
filePath: relative(this.servicePath, source),
key,
name,
}),
type: 'file',
};
});
} catch ({ message }) {
this.serverless.cli.log(message);
}
};

return new Promise((resolve, reject) => {
output.on('close', () => resolve(artifactFilePath));
output.on('error', (err) => reject(err));
Expand All @@ -277,7 +369,8 @@ module.exports = class {
),
);

SortBy(contents, ['filePath']).forEach((file) => {
const pnpLinks = Flatten(contents.map(revertPnp)).filter(Boolean);
SortBy(contents.concat(pnpLinks), ['filePath']).forEach((file) => {
const { filePath, data, stat, ...rest } = file;
let { mode } = stat;

Expand Down Expand Up @@ -328,11 +421,10 @@ module.exports = class {

const handleFile = (pathname) => {
const realpath = realpathSync(pathname);

const cache = this.files.find(([src]) => src === realpath);

if (Array.isArray(cache)) {
const [fullpath] = cache;
const [, fullpath] = cache;
if (fullpath) {
return readFileSync(fullpath, 'utf-8');
}
Expand Down Expand Up @@ -371,13 +463,15 @@ module.exports = class {

const nativeResolve = (id, parent) => {
return require.resolve(id, {
paths: [parent, dirname(parent)],
paths: [parent, dirname(parent), this.servicePath, __filename],
});
};

const fallbackResolve = (id, parent, { previous } = {}) => {
const pathStack = parent.split(sep);
if (pathStack.includes('node_modules') || pathStack.includes('.yarn')) {
if (
parent.split(sep).includes('node_modules') ||
/^\.yarn/.test(relative(this.servicePath, parent))
) {
return nativeResolve(id, parent);
}

Expand All @@ -404,7 +498,7 @@ module.exports = class {
return nativeResolve(previous, parent);
}

return fallbackResolve(join(id, 'index'), parent, {
return fallbackResolve('./' + join(id, 'index'), parent, {
tryAgain: false,
previous: id,
});
Expand All @@ -413,7 +507,7 @@ module.exports = class {
return nativeResolve(id, parent);
};

const { fileList = [] } = await FileTrace([entrypoint], {
const { fileList = [], warnings } = await FileTrace([entrypoint], {
base: this.servicePath,
readLink: handleFile,
readFile: handleFile,
Expand All @@ -434,6 +528,10 @@ module.exports = class {
},
});

warnings.forEach(({ message }) => {
this.serverless.cli.log(message);
});

const patterns = excludes
.map((p) => (p.charAt(0) === '!' ? p.substring(1) : `!${p}`))
.concat(includes)
Expand Down Expand Up @@ -475,7 +573,74 @@ module.exports = class {
);
}

return SortBy(filePaths, (pathname) => {
const appendPkgs = async (filePaths) => {
// eslint-disable-next-line block-scoped-var
if (!locatorMap) {
return filePaths;
}

return Uniq(
Flatten(
await Map(filePaths, async (pathname) => {
if (basename(pathname) === 'package.json') {
return pathname;
}

return [
pathname,
relative(
this.servicePath,
await pkgUp({
cwd: dirname(join(this.servicePath, pathname)),
}),
),
];
}),
),
);
};

const filePathsWPkgs = await appendPkgs(filePaths);

// eslint-disable-next-line block-scoped-var
if (tsAvailable) {
filePathsWPkgs
.filter((pathname) => {
return !(
pathname.split(sep).includes('node_modules') ||
/^\.yarn/.test(pathname) ||
basename(pathname) !== 'package.json'
);
})
.forEach((pathname) => {
const fullpath = join(this.servicePath, pathname);
const pkg = require(fullpath);
const { main } = pkg;

if (!main) {
return;
}

const ext = extname(main);
if (!['.tsx', '.ts'].includes(ext)) {
return;
}

const newPkg = {
...pkg,
main: main.replace(/\.tsx|\.ts$/, ''),
};

this.files.push([
fullpath,
writeSync(JSON.stringify(newPkg, null, 2), {
extension: '.json',
}),
]);
});
}

return SortBy(filePathsWPkgs, (pathname) => {
return pathname.split(sep).includes('package.json');
});
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"mz": "^2.7.0",
"nanomatch": "^1.2.13",
"path-is-inside": "^1.0.2",
"pkg-up": "^3.1.0",
"tempy": "^0.7.0"
},
"devDependencies": {
Expand Down
10 changes: 10 additions & 0 deletions test/__fixtures__/js-nm-individually/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7369,6 +7369,15 @@ fsevents@~2.1.2:
languageName: node
linkType: hard

"pkg-up@npm:^3.1.0":
version: 3.1.0
resolution: "pkg-up@npm:3.1.0"
dependencies:
find-up: ^3.0.0
checksum: 3/df82763250b5283c175918f9410f9651afc1750f951249b31c7c49a6918d9faf13a9ef11e9355cbb0d4d5039a5c9d4c7162755b3e6c26235d2e3baea086e4a54
languageName: node
linkType: hard

"please-upgrade-node@npm:^3.2.0":
version: 3.2.0
resolution: "please-upgrade-node@npm:3.2.0"
Expand Down Expand Up @@ -8255,6 +8264,7 @@ fsevents@~2.1.2:
nanomatch: ^1.2.13
path-is-inside: ^1.0.2
path-type: ^4.0.0
pkg-up: ^3.1.0
prettier: ^2.1.2
pretty-bytes: ^5.4.1
pretty-ms: ^7.0.0
Expand Down
10 changes: 10 additions & 0 deletions test/__fixtures__/js-nm-single/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7369,6 +7369,15 @@ fsevents@~2.1.2:
languageName: node
linkType: hard

"pkg-up@npm:^3.1.0":
version: 3.1.0
resolution: "pkg-up@npm:3.1.0"
dependencies:
find-up: ^3.0.0
checksum: 3/df82763250b5283c175918f9410f9651afc1750f951249b31c7c49a6918d9faf13a9ef11e9355cbb0d4d5039a5c9d4c7162755b3e6c26235d2e3baea086e4a54
languageName: node
linkType: hard

"please-upgrade-node@npm:^3.2.0":
version: 3.2.0
resolution: "please-upgrade-node@npm:3.2.0"
Expand Down Expand Up @@ -8255,6 +8264,7 @@ fsevents@~2.1.2:
nanomatch: ^1.2.13
path-is-inside: ^1.0.2
path-type: ^4.0.0
pkg-up: ^3.1.0
prettier: ^2.1.2
pretty-bytes: ^5.4.1
pretty-ms: ^7.0.0
Expand Down
10 changes: 10 additions & 0 deletions test/__fixtures__/js-pnp-individually/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7369,6 +7369,15 @@ fsevents@~2.1.2:
languageName: node
linkType: hard

"pkg-up@npm:^3.1.0":
version: 3.1.0
resolution: "pkg-up@npm:3.1.0"
dependencies:
find-up: ^3.0.0
checksum: 3/df82763250b5283c175918f9410f9651afc1750f951249b31c7c49a6918d9faf13a9ef11e9355cbb0d4d5039a5c9d4c7162755b3e6c26235d2e3baea086e4a54
languageName: node
linkType: hard

"please-upgrade-node@npm:^3.2.0":
version: 3.2.0
resolution: "please-upgrade-node@npm:3.2.0"
Expand Down Expand Up @@ -8255,6 +8264,7 @@ fsevents@~2.1.2:
nanomatch: ^1.2.13
path-is-inside: ^1.0.2
path-type: ^4.0.0
pkg-up: ^3.1.0
prettier: ^2.1.2
pretty-bytes: ^5.4.1
pretty-ms: ^7.0.0
Expand Down
10 changes: 10 additions & 0 deletions test/__fixtures__/js-pnp-single/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7369,6 +7369,15 @@ fsevents@~2.1.2:
languageName: node
linkType: hard

"pkg-up@npm:^3.1.0":
version: 3.1.0
resolution: "pkg-up@npm:3.1.0"
dependencies:
find-up: ^3.0.0
checksum: 3/df82763250b5283c175918f9410f9651afc1750f951249b31c7c49a6918d9faf13a9ef11e9355cbb0d4d5039a5c9d4c7162755b3e6c26235d2e3baea086e4a54
languageName: node
linkType: hard

"please-upgrade-node@npm:^3.2.0":
version: 3.2.0
resolution: "please-upgrade-node@npm:3.2.0"
Expand Down Expand Up @@ -8255,6 +8264,7 @@ fsevents@~2.1.2:
nanomatch: ^1.2.13
path-is-inside: ^1.0.2
path-type: ^4.0.0
pkg-up: ^3.1.0
prettier: ^2.1.2
pretty-bytes: ^5.4.1
pretty-ms: ^7.0.0
Expand Down

0 comments on commit 20a1c5e

Please sign in to comment.