Skip to content

Instantly share code, notes, and snippets.

@SiZapPaaiGwat
Created December 1, 2023 02:01
Show Gist options
  • Save SiZapPaaiGwat/9feda8763a9eedd89feb7b0688fd2d94 to your computer and use it in GitHub Desktop.
Save SiZapPaaiGwat/9feda8763a9eedd89feb7b0688fd2d94 to your computer and use it in GitHub Desktop.
pick-deps
/* eslint-disable */
const fs = require('fs');
const path = require('path');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const copy = require('recursive-copy');
/* eslint-enable */
const outDir = 'src'
const publicDir = 'public'
const webpackAlias = '@'
const homeDir = webpackAlias + '/'
const publicDirs = [publicDir + '/', '/' + publicDir]
const scriptExts = ['.ts', '.tsx', '.js', '.jsx']
const extensions = [...scriptExts, ...scriptExts.map(i => `/index${i}`)];
const localPath = ['./', '../', homeDir, ...publicDirs];
const rootPath = process.cwd();
const destinationPath = path.join(rootPath, outDir);
const currentPkgJsonPath = path.join(rootPath, 'package.json');
const currentPkgJson = JSON.parse(fs.readFileSync(currentPkgJsonPath, 'utf8'));
const handledFiles = new Set();
const npmDependencies = new Set();
/**
* Returns the file path with the correct extension.
* If the file path already has an extension, it is returned unchanged.
*
* @param {string} filePath - The file path to check for extension.
* @return {string} The file path with the correct extension.
*/
function getFilePathWithExtension(filePath) {
if (/\.\w+$/.test(filePath)) {
return filePath
}
for (let ext of extensions) {
let filePathWithExt = filePath + ext;
if (fs.existsSync(filePathWithExt)) {
return filePathWithExt;
}
}
throw new Error(`File "${filePath}" does not exist.`);
}
async function main(entry, ignoredPath) {
function parseAndHandleFile(rawFilePath) {
const filePath = getFilePathWithExtension(rawFilePath);
if (handledFiles.has(filePath) || ignoredPath.some(i => filePath.includes(i))) {
return;
}
handledFiles.add(filePath);
if (!scriptExts.includes(path.extname(filePath))) {
console.log('Not a JavaScript or TypeScript file:', filePath);
return
}
const fileContent = fs.readFileSync(filePath, 'utf8');
const ast = parser.parse(fileContent, {
sourceType: 'module',
plugins: ['jsx', 'typescript'],
});
traverse(ast, {
ImportDeclaration({ node }) {
const dependencyPath = node.source.value;
// ./ ../ @/ public /public
if (localPath.some(p => dependencyPath.startsWith(p))) {
let absoluteDependencyPath;
if (dependencyPath.startsWith(homeDir)) {
absoluteDependencyPath = path.join(rootPath, dependencyPath.slice(2));
} else if (publicDirs.some(p => dependencyPath.startsWith(p))) {
absoluteDependencyPath = path.join(rootPath, dependencyPath.startsWith('/') ? dependencyPath.slice(1) : dependencyPath);
} else {
absoluteDependencyPath = path.resolve(path.dirname(filePath), dependencyPath);
}
parseAndHandleFile(absoluteDependencyPath);
} else {
npmDependencies.add(dependencyPath);
}
},
});
}
const sourceFilePath = path.join(rootPath, entry);
const packageJson = {
...currentPkgJson,
dependencies: {},
};
parseAndHandleFile(sourceFilePath);
for (let file of handledFiles) {
copy(file, file.replace(rootPath, destinationPath), {
overwrite: true
})
}
npmDependencies.forEach(dependency => {
if (currentPkgJson.dependencies[dependency]) {
packageJson.dependencies[dependency] = currentPkgJson.dependencies[dependency]
}
});
fs.writeFileSync(path.join(destinationPath, 'package.json'), JSON.stringify(packageJson, null, 2));
}
main('pages/landing/edit-page.tsx', ['components/Header', 'components/Footer'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment