Skip to content

(feat): closure compiler for minification#525

Closed
ambroseus wants to merge 13 commits into
jaredpalmer:masterfrom
ambroseus:feature/closure-compiler
Closed

(feat): closure compiler for minification#525
ambroseus wants to merge 13 commits into
jaredpalmer:masterfrom
ambroseus:feature/closure-compiler

Conversation

@ambroseus

@ambroseus ambroseus commented Feb 28, 2020

Copy link
Copy Markdown
Contributor

Related to #358
(for internal use only :)
Added ability to use closure compiler instead of terser plugin for code minification

"build": "tsdx build --closureCompiler"

to play with advanced options use tsdx.config.js

const closureCompiler = require('@ampproject/rollup-plugin-closure-compiler');

const closureCompilerPlugin = closureCompiler({
  compilation_level: 'ADVANCED_OPTIMIZATIONS',
});

module.exports = {
  rollup(config) {
    config.plugins = config.plugins.map(plugin => {
      // override closure compiler plugin's default config
      if (plugin && plugin.name === closureCompilerPlugin.name) {
        return closureCompilerPlugin;
      }
      return plugin;
    });

    return config;
  },
};

@agilgur5 agilgur5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments. microbundle has a similar discussion in developit/microbundle#569 which seems to have some bugs(?) but behind an experimental flag or something it could be ok

Comment thread src/createRollupConfig.ts Outdated
Comment thread src/createRollupConfig.ts Outdated
Comment thread src/createRollupConfig.ts Outdated
@ambroseus

Copy link
Copy Markdown
Contributor Author

@agilgur5 please review:
--closureCompiler CLI flag
closureComplierOptions section in tsdx.config.js

@ambroseus ambroseus changed the title Feature: closure compiler for minification (feat): closure compiler for minification Mar 9, 2020

@agilgur5 agilgur5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the changes @ambroseus .

I've left a few comments here, but the key concepts:

  • I don't think we want to open up the tsdx.config.js API just yet, that needs some more thought process. Also may have misinterpreted my previous comments -- I meant to just add the config you had as a default and can customize through existing config.plugins style.
  • The tests right now don't test if Closure was used instead of Terser, they just check that setting the --closureCompiler flag (and configuring Closure) doesn't fail. I'm fine with leaving out tests right now since this is experimental, so maybe just delete them.
    • I'm not sure what tests for this should look like. Maybe snapshots are appropriate (like microbundle did) though I'm not a big fan of them.
    • No need for a new fixture directory if tests are added, can re-use build-default if just using the flag, and can use build-withConfig for configuring it (though that's not yet set-up for automated testing). Maybe configuring it and ensuring the configuration succeeded is an appropriate test. But I'm not sure how we'd do that without a snapshot either

Comment thread src/index.ts Outdated
Comment thread test/fixtures/build-compiler/src/syntax/nullish-coalescing.ts
Comment thread test/tests/tsdx-build.test.js Outdated
Comment thread test/tests/tsdx-build.test.js Outdated
Comment thread src/createBuildConfigs.ts Outdated
Comment thread src/createRollupConfig.ts Outdated
Comment thread test/fixtures/build-compiler/package.json Outdated
@agilgur5

Copy link
Copy Markdown
Collaborator

Yea, I think it's fine to leave tests out for now, don't want to add too much iteration for you since I'm not really sure myself what those should look like and build-withConfig isn't yet set-up for automated tests. Feel free to share any ideas on that front though

@ambroseus

Copy link
Copy Markdown
Contributor Author

@agilgur5 so... may be my first approach with dedicated closureCompileOptions config file and env var instead of --closureCompiler flag is more applicable considering this is INTERNAL UNSTABLE VERY SECRET feature? ;)

@jaredpalmer

Copy link
Copy Markdown
Owner

I think snapshots on code output make sense here for testing. It may be hard to understand prod output. While it’s not exactly an integration test, perhaps we could run prettier on the prod output of the test before the snapshot so it’s at least readable.

While this experimental, if it works, I can’t see why we wouldn’t use it in core. IIRC React core uses it.

A plugin system is beyond the scope of this issue, but a good one. My 2cents on this, is that unlike Gatsby who’s core does almost nothing, TSDX’s core should be the happy path and cover 80-90% of use cases.

@agilgur5

Copy link
Copy Markdown
Collaborator

@agilgur5 so... may be my first approach with dedicated closureCompileOptions config file and env var instead of --closureCompiler flag is more applicable considering this is INTERNAL UNSTABLE VERY SECRET feature? ;)

Well I don't think it's "very secret" given this public PR haha 😝
But I think opening up two new, different API surfaces (a dedicated config file and an env var) is much more confusing than just adding a flag.
And I'm totally fine with getting feedback from the community on an "unstable experimental" feature, it doesn't have to be internal-only. This is the same way React and Rollup have incrementally released features too, though usually they'll initially prefix them as unstable_ or experimental before.

It can be configured in tsdx.config.js with config.plugins already, so let's just use the same method for now.

While this experimental, if it works, I can’t see why we wouldn’t use it in core.

Based on microbundle's work in developit/microbundle#569 and @ambroseus's testing in #358, it sounds like it's not always better than Terser (but often is?). ADVANCED_OPTIMIZATIONS might also take longer or use more memory than Terser, but it wasn't clear to me if it necessarily did.

A plugin system is beyond the scope of this issue, but a good one.

I still need to write up an RFC for this but I have it in my head. The plugin system would be more to make common use cases of tsdx.config.js easier. Because they often require additional dependencies or don't apply to everyone, it makes sense for it to be out of core, but perhaps still maintained internally for better maintainability against changes to the internal configs (and because they're common).
There's also a separate use of the word "plugin" in that a good bit of TSDX could probably be re-written as a Rollup plugin(s)

@ambroseus ambroseus force-pushed the feature/closure-compiler branch from a7832c5 to f22343b Compare March 14, 2020 11:18
@ambroseus ambroseus requested a review from agilgur5 March 14, 2020 20:24
@ambroseus

ambroseus commented Mar 14, 2020

Copy link
Copy Markdown
Contributor Author

@agilgur5 @jaredpalmer please, review

there are some closure-compiler specific tests. only CC can minify this:

import { split } from './foo';

export const sum = (a: number, b: number) => {
  return a + b;
};

const bar = split('bar');

export const signature = `${split('bar').join('')} ${sum(bar.length, -3)}`;

to this:

var signature="bar 0";function sum(a,b){return a+b};export{signature,sum}

terser's output to compare:

var n=function(n){return n.split("")},r=function(n,r){return n+r},t=n("bar"),
e=n("bar").join("")+" "+r(t.length,-3);export{e as signature,r as sum};

@agilgur5 agilgur5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on making a closure compiler specific test!! Would be great to get another test that only ADVANCED_OPTIMIZATIONS can do if it's not too difficult/involved.

I left some comments on a few small things, but more generally I still don't think we should add a closureCompilerOptions section yet, that's something we can think about/discuss in the future, possibly in my plugins RFC. I added a suggestion to the tsdx.config.closure-advanced.js for what to use for this for now.

I'm also going to move the existing manual tests that are in the withConfig fixture to an integration tests set-up, I'll rebase this after so that the code that's already here isn't deleted, but moved instead. Don't worry about doing anything for this, it's just a step I'll need to do before merging.

Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
output = shell.grep('bar 0', [
'dist/build-withconfig.esm.production.min.js',
]);
expect(/bar 0/.test(output.stdout)).toBeTruthy();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there another simple test we can add to this that only ADVANCED_OPTIMIZATIONS can do?

Comment thread test/fixtures/build-withConfig/src/index.ts
Comment thread test/fixtures/build-withConfig/tsdx.config.closure-simple.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
Comment thread src/createRollupConfig.ts Outdated
Comment thread test/fixtures/build-withConfig/tsdx.config.closure-advanced.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
@ambroseus ambroseus force-pushed the feature/closure-compiler branch from 60c6a28 to 11c5862 Compare March 20, 2020 11:10
@ambroseus

Copy link
Copy Markdown
Contributor Author

@agilgur5 next round), please review

Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated

@agilgur5 agilgur5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some minor things around explicitness, comments, and style. All the major pieces are in line!!

Comment thread test/fixtures/build-withConfig/src/index.ts Outdated
Comment thread test/fixtures/build-withConfig/src/index.ts Outdated
Comment thread src/createRollupConfig.ts Outdated
@ambroseus

Copy link
Copy Markdown
Contributor Author

@agilgur5 final (maybe:) round, please review

@agilgur5 agilgur5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is basically good to go. Just one q on the patterns in-line

There's a few nits here, but I can edit those myself as this needs to get rebased and updated to the new testing set-up anyway.

Comment thread test/fixtures/util.js Outdated
it('should minify bundle with default options', () => {
util.setupStageWithFixture(stageName, 'build-withConfig');

let output = shell.exec('node ../dist/index.js build --closureCompiler');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

util.setupStageWithFixture(stageName, 'build-withConfig');
shell.mv('-f', 'tsdx.config.closure-advanced.js', 'tsdx.config.js');

let output = shell.exec('node ../dist/index.js build --closureCompiler');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
Comment thread test/tests/tsdx-build-closure-compiler.test.js Outdated
const esmBundle = 'dist/build-withconfig.esm.js';

const simplePattern = /exports\.signature=signature/;
const advancedPattern = /exports\.a="bar 0"/;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh... doesn't this minification break the usage?? since signature is no longer exported. is that a bug in closure or is there a way to disable exports minification?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agilgur5 hmm.. this is not good.. need to investigate (a lot of ADVANCED options)

@agilgur5 agilgur5 Mar 29, 2020

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I haven't looked the API at all. Keywords would likely be "exports" and "mangle" as I believe the technical term for changing variable names is "mangling"

At least we're already iterating on some future defaults 😅

@agilgur5

agilgur5 commented Apr 8, 2020

Copy link
Copy Markdown
Collaborator

While this is waiting for more changes, figure I should credit you in allcontributors for your contributions especially since a piece of the code here went into #627 already.

@agilgur5

agilgur5 commented Apr 8, 2020

Copy link
Copy Markdown
Collaborator

@allcontributors please add @ambroseus for test, examples, questions, ideas

@allcontributors

Copy link
Copy Markdown
Contributor

@agilgur5

I've put up a pull request to add @ambroseus! 🎉

@ambroseus

Copy link
Copy Markdown
Contributor Author

@agilgur5 thanks! proud to work with tsdx team and you personally :)

@ambroseus

Copy link
Copy Markdown
Contributor Author

@agilgur5 rebased & moved tests to integration folder. please check)

@agilgur5 agilgur5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a few bugs that came in from merge conflict resolution that need to be fixed.

A few of the remaining comments from last review haven't been resolved yet, like const instead of let, and most notably the exports.a name mangling with ADVANCED_OPTIMIZATIONS. That one's the big blocker here. Any other changes I could quickly fix myself to push this out, but that one's more involved and part of the core work you've been doing. So focus your time on that as first priority.


integration is also the wrong directory to put this 😅 This isn't an integration test as Closure Compiler is being added as a feature, not an external integration. It would go into e2e.
But as I said before, don't worry too much about that, I can make those changes myself when this is ready as the test structure and organization changed quite a bit and I'm much more familiar with that (there's also some issues here with beforeEach, let instead of const, expect(output.code) that could be placed differently, etc). Please focus on the other changes above.

Thanks for iterating on this and trying to tackle that mess of a rebase yourself!

Comment thread src/env.d.ts
Comment thread yarn.lock
Comment thread test/integration/tsdx-build-withClosure.test.ts
@ambroseus

Copy link
Copy Markdown
Contributor Author

@agilgur5 ... time is going) I thought a lot about this feature and decide to close PR, because it's not very useful right now. We can implement it later as tsdx plugin for ex.

@ambroseus ambroseus marked this pull request as draft May 27, 2020 05:31
@ambroseus ambroseus closed this May 27, 2020
@ambroseus ambroseus deleted the feature/closure-compiler branch May 27, 2020 05:35
@agilgur5 agilgur5 added kind: feature New feature or request solution: unresolved Issue has been closed by OP but root cause has not necessarily been resolved labels Aug 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind: feature New feature or request solution: unresolved Issue has been closed by OP but root cause has not necessarily been resolved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add closure compiler

3 participants