organize-imports-cli
organize-imports-cli copied to clipboard
Suggestions on performance improving
TL;DR: A little bit changes to the options of the Project
constructor will greatly reduce the time consuming during the initializing of the new instance.
const project = new Project({
tsConfigFilePath,
manipulationSettings,
// **The real problem here**
// Should set to false and add files needed manually
addFilesFromTsConfig: false,
// Can reduce a chunk of time if added alone without other options
skipFileDependencyResolution: true,
// Not important, but a better-have theoreticallly
compilerOptions: { isolatedModules: true },
});
In most daily cases, imports organizing only deal with files on a one-to-one basis. There is no need to know the whole detail of the project(s), nor the dependency relations of every single file. The only thing wo do need is the pure AST.
Currently, the default options of the Project
constructor, which defined by ts-morph
, is quite opposite to our ideal scenario:
https://github.com/dsherret/ts-morph/blob/e769b7871982ca874684e20355d58f1153efdcda/packages/ts-morph/src/Project.ts#L11-L34
FYI, we use organize-imports-cli
in a middle size project, managed by lerna
, with dozens of inline packages. That means, when commited files scatter acrose several packages, each package will produce an instance of Project
, and each instance costs 3 seconds on average, because ts-morph
is trying to load all the files during initializing, though most of them are totally irrelevant.
I have tried modify the code locally, and passed all the tests, except the excluded test
, which is caused by addFilesFromTsConfig
. So if you are willing to alter the options, there will be some more effort needed to deal with file resolving when included files defined in the tsconfig.json
are really all needed. But for almost all daily cases, it will just works fine.
I'm not sure how compiler options and dependency resolution affect organizing imports. It looks like they shouldn't really affect it, but still I'm somehow sure there are tricky edge cases I'm not aware of.
What if we add an explicit --skip-tsconfig
flag? With it tsconfig.json
won't be resolved and default settings will be used. Thoughts?
I just tested the following code and it works fine for me.
// cli.js:L45
/**
* @type {Record<string, {
* files: 'all' | SourceFile[]
* project: import('ts-morph').Project,
* detectNewLineKind: boolean,
* }>}
*/
const projects = {};
const defaultProject = new Project();
defaultProject.addSourceFilesAtPaths(filePaths);
projects.defaultProject = {
project: defaultProject,
files: defaultProject.getSourceFiles(),
};
// The whole `for` loop is commented out, for test purpose only
// for (const filePath of filePaths) {
// const tsConfigFilePath = tsconfig.findSync(path.dirname(filePath));
I agree with the --skip-tsconfig
idea, but I think the flag name itself might be a little confusing. IMO the --list-different
is quite straight forward, but --skip-tsconfig
is relatively harder to understand without further explanation.
Though I don't have a clear idea neither, how about --isolated-modules
or --isolated-files
, which refers to the compiler option --isolatedModules
from Typescript
. Or maybe anything else conveys "Treat every input as individual file only". The choice is yours.
--isolated-modules
sounds great.
Any updates?
@afterwind-io @thorn0 The suggested options can be added to https://github.com/thorn0/organize-imports-cli/blob/master/cli.js#L74 & https://github.com/thorn0/organize-imports-cli/blob/master/cli.js#L103-L105. Is this correct? Happy to open a PR to have this shipped.
@glennreyes
It has been quite a while and if I recall correctly...
https://github.com/thorn0/organize-imports-cli/blob/master/cli.js#L74
Yes.
https://github.com/thorn0/organize-imports-cli/blob/master/cli.js#L103-L105
Not sure. Seems yes. Haven't tried manipulating this before.
It's the opposite. The first link leads to a code path where tsconfig is used. We want to skip it when the new flag is specified. Please go ahead with the PR @glennreyes.
it's much faster for my project after disabling the line below, are there any consequences?
this line took 5-6 seconds
const project = new Project({ tsConfigFilePath, manipulationSettings });
if (tsConfigFilePath && !projectEntry && false) {
format a file before: 9.5s after: 2.24s
Would love to have this feature added