Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Very slow builds with many types (especially vue single file components) #988

Closed
WolfspiritM opened this issue Aug 12, 2019 · 3 comments
Closed
Labels

Comments

@WolfspiritM
Copy link

WolfspiritM commented Aug 12, 2019

Expected Behaviour

Fast compile

Actual Behaviour

Very slow compile

Steps to Reproduce the Problem

Check out https://github.com/WolfspiritM/TypeScript-Vue-Starter
Run "npm install" and "npm run build"
Compile takes more then 30 Seconds (48 Seconds in my case).
The project has about 40 very simple SFCs and has types loaded (especially lodash-es seems to cause troubles as it is so big I think).

I debugged the reason for the very slow build and found out that ts-loader is trying to compile every single file it receives from webpack. That in itself isn't a problem but for each file the languageservice creates a new program with the call to getProgram(). Everytime it creates a new program it reuses ALL files it ever read before (https://github.com/TypeStrong/ts-loader/blob/master/src/servicesHost.ts#L105) as rootfiles (https://github.com/microsoft/TypeScript/blob/825d8bb1dc0c5bae2c0996e538825111f65d07dd/src/services/services.ts#L884) and creates a sourcefile from it which ends up becoming very very slow. The rootfiles array includes for example d.ts files from node_modules aswell.

For normal projects getProgram() will not return a new program cause the rootfiles didn't change from the initial files. Usually all included files are loaded by reading include, exclude and files results from tsconfig but for vue this doesn't work as tsconfig only reads *.ts or *.tsx files.

Any idea how this could be handled better?

I tried to exclude node_modules from getScriptFileNames which seems to have made it a bit faster but the best solution I think would be to somehow resuse the old program. The reason why it doesn't reuse it is that the files root files change.

This is what a did for testing. It made the compiling 20 Seconds faster but not sure if this might break something:

    const filesCache = new Map(files);
    const servicesHost = {
        getProjectVersion: () => `${instance.version}`,
        getProjectReferences: () => projectReferences,
        getScriptFileNames: () => [...files.keys()].filter(filePath => filePath.match(scriptRegex)),
        getScriptVersion: (fileName) => {
            fileName = path.normalize(fileName);
            const file = files.get(fileName);
            return file === undefined ? '' : file.version.toString();
        },
        getScriptSnapshot: (fileName) => {
            // This is called any time TypeScript needs a file's text
            // We either load from memory or from disk
            fileName = path.normalize(fileName);
            let file = filesCache.get(fileName);
            if (file === undefined) {
                file = files.get(fileName);
                if (file === undefined) {
                    const text = utils_1.readFile(fileName);
                    if (text === undefined) {
                        return undefined;
                    }
                    file = { version: 0, text };
                    filesCache.set(fileName, file);
                }
            }
            return compiler.ScriptSnapshot.fromString(file.text);
        },
@johnnyreilly
Copy link
Member

Heya,

I was going to recommend switching to transpileOnly and using ts-loader with fork-ts-checker-webpack-plugin. But I recognise your avatar and guess you already know that!

I don't have any particular recommendations at present. But if you want to experiment and submit speculative PRs I'll happily take a look!

@stale
Copy link

stale bot commented Oct 11, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Oct 11, 2019
@stale
Copy link

stale bot commented Oct 18, 2019

Closing as stale. Please reopen if you'd like to work on this further.

@stale stale bot closed this as completed Oct 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants