Skip to content

Commit

Permalink
Merge pull request #693 from forcedotcom/mz/bundle-checks
Browse files Browse the repository at this point in the history
Mz/bundle checks
  • Loading branch information
iowillhoit authored Oct 29, 2024
2 parents f351662 + 7d27950 commit 1f0a134
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 7 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ jobs:
yarn-lockfile-check:
uses: salesforcecli/github-workflows/.github/workflows/lockFileCheck.yml@main
# Since the Windows unit tests take much longer, we run the linux unit tests first and then run the windows unit tests in parallel with NUTs
test-bundle:
runs-on: ubuntu-latest
name: test bundling
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: yarn
- uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@main
- name: Build the project
run: yarn build
- name: check if bundling runs into failures
run: node scripts/testEsbuild.js
linux-unit-tests:
needs: yarn-lockfile-check
uses: salesforcecli/github-workflows/.github/workflows/unitTestsLinux.yml@main
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ lerna-debug.log

# compile source
lib
dist

# test artifacts
*xunit.xml
Expand Down
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
. "$(dirname "$0")/_/husky.sh"

yarn lint && yarn pretty-quick --staged
node ./scripts/scanTs.js
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
},
"dependencies": {
"@oclif/core": "^4.0.23",
"@salesforce/core": "^8.6.1",
"@salesforce/core": "^8.6.2",
"@salesforce/kit": "^3.2.3",
"@salesforce/source-deploy-retrieve": "^12.7.4",
"@salesforce/source-deploy-retrieve": "^12.8.1",
"@salesforce/ts-types": "^2.0.12",
"fast-xml-parser": "^4.5.0",
"graceful-fs": "^4.2.11",
Expand All @@ -64,7 +64,9 @@
"@salesforce/dev-scripts": "^10.2.10",
"@salesforce/schemas": "^1.9.0",
"@types/graceful-fs": "^4.1.9",
"esbuild": "^0.24.0",
"eslint-plugin-sf-plugin": "^1.20.8",
"ts-morph": "^24.0.0",
"ts-node": "^10.9.2",
"ts-patch": "^3.2.1",
"typescript": "^5.6.2"
Expand Down
29 changes: 29 additions & 0 deletions scripts/esbuild.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* NOTE: This file does NOT really generate a bundle version of source-tracking
* source-tracking is bundled directly in salesforcedx-vscode
* The file is only used to detect any potential risks to esbuild.
**/
const { build } = require('esbuild');

const sharedConfig = {
bundle: true,
format: 'cjs',
platform: 'node',
external: [], // The whitelist of dependencies that are not bundle-able
keepNames: true,
plugins: [],
supported: {
'dynamic-import': false,
},
logOverride: {
'unsupported-dynamic-import': 'error',
},
};

(async () => {
await build({
...sharedConfig,
entryPoints: ['./lib/index.js'],
outdir: 'dist',
});
})();
50 changes: 50 additions & 0 deletions scripts/scanTs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const fs = require('fs');
const path = require('path');
const { Project, CallExpression } = require('ts-morph');

const SRC_DIR = path.join(__dirname, '..', 'src');
const project = new Project({
tsConfigFilePath: path.join(__dirname, '..', 'tsconfig.json'),
});

let detected = false;
const scanDirectory = (dir) => {
const files = fs.readdirSync(dir);
files.forEach((file) => {
const fullPath = path.join(dir, file);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
scanDirectory(fullPath);
} else if (fullPath.endsWith('.ts')) {
analyzeFile(fullPath);
}
});
};

// This function will detect all the usages of fs.read* and send warnings with the location of the usage
const analyzeFile = (filePath) => {
const srcFile = project.addSourceFileAtPath(filePath);
const funcCalls = srcFile.getDescendantsOfKind(CallExpression);

funcCalls.forEach((callExpression) => {
const exp = callExpression.getExpression();
if (exp.getText().startsWith('fs.read')) {
detected = true;
console.warn(
`Warning: Usage of "${exp.getText()}" in file "${filePath}" at line ${callExpression.getStartLineNumber()}.\n`
);
}
});
};

scanDirectory(SRC_DIR);

if (detected) {
console.log('The warnings above do not mean the usages are wrong.');
console.log(`Avoid reading local artifacts with "fs.read*" since esbuild cannot bundle the artifacts together.`);
console.log('Consider using import instead or reach out to IDEx Foundations team');
} else {
console.log('No fs.read* usages detected.');
}

console.log('Scan complete');
17 changes: 17 additions & 0 deletions scripts/testEsbuild.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const { exec } = require('child_process');

exec('node ./scripts/esbuild.config.js', (error, stdout, stderr) => {
// Combine stdout and stderr to check the entire output
const output = `${stdout}\n${stderr}`;
if (error) {
console.error(stderr);
process.exit(1); // Exit with an error code
}
// Check if the output contains the error string
if (output.includes('[require-resolve-not-external]')) {
console.error('Error: A dependency that has to be externalized in esbuild process is found. Please resolve it!');
process.exit(1); // Exit with an error code
} else {
process.exit(0); // Exit with success code
}
});
Loading

0 comments on commit 1f0a134

Please sign in to comment.