Skip to content

feat(npm-scripts): add minification to build process#233

Merged
wincent merged 7 commits intomasterfrom
wincent/minify
Nov 25, 2020
Merged

feat(npm-scripts): add minification to build process#233
wincent merged 7 commits intomasterfrom
wincent/minify

Conversation

@wincent
Copy link
Copy Markdown
Contributor

@wincent wincent commented Nov 11, 2020

This is a far-from-finished WIP, but parking it here anyway for safe-keeping: (upgrading this from WIP to POC)

Final status:

  • Discussed in Slack here:
    - The JS-in-JSP minification works if you run yarn build by hand, but when run as part of a gradle invocation the jobs happen in the wrong order for our purposes — we can't minify the JS in JSP in classes/ because it only gets put there after packageRunBuild. The conclusion of the Slack thread is that we can leave the code in here as a kind of benign no-op, and if we decide to prioritize the necessary changes on the Gradle side it will "magically" start working. If it's still there months from now and it looks like we're never going to get to it we can just rip it out.

    Excerpts from the Slack thread:

    its possible

    we would need to change the src path to the new output files first when we compile

    and also replace the jsps used to build the jars

    and:

    in terms of whether or not it's worth doing. my quick-and-dirty metrics show that for typical JS we see a reduction of about 42.7% (in pre-gzip byte count), and in terms of how much JS-in-JSP we have on the table, at the moment it is about this much under modules/:

    • Files: 890
    • Tags: 1102 (<script> or aui:script)
    • Lines: 43634 (inside tags)
    • Bytes: 1237555 (inside tags)

    so, at the moment with runtime minification done by the Java JS minifier, we get a fair bit of compression for that stuff, but once LPS-122883 is done the expectation is that we turn runtime minification off by default and do it all ahead of time as I'm describing above.

  • Also discussed release here. I still haven't got source maps working, but so as to keep this rolling forward I am going to proceed with the merge and fast-follow with a fix as soon as I find it. Otherwise this could drag on for days or more.


Here's the gist. This implements the first couple of parts of the idea described in the research doc.

Namely, if we're not in development mode, we pre-minify JS resources before they are served. Using Terser because it's the current king (16.7 M weekly downloads) and the former champion (Uglify) is no longer maintained. babel-minify is still labeled as in beta and sees little activity. For some more context, here is a comparison from 2019.

Screenshot 2020-11-11 -143053-7SdueySE@2x

At the moment, I developed this just enough to get some numbers. Here is what we see in frontend-js-react-web, which is a good example of an OSGi module containing some "own JS" + dependencies in node_modules.

Summary:
  Files minified:    806
  Files with errors: 169
  Before size:       3561639
  After size:        878708
  Delta:             2682931
  Elapsed:           8.88

Sizes are just raw bytes, ignoring gzip, so the "real" size in a production environment would be much less, obviously (but so will the savings).

Lots of files with errors, but at a glance, most of those look legit, because our bundler will take every file in the graph and AMD wrap it even if it shouldn't be wrapped (due to config, or whatever), so we wind up with illegal JS in the JAR that will never get used (like files with import statements inside AMD factory definitions).

The approach is to minify all the JS as a last step in the build process. This way we cover JS that came in from yarn install and the bundler, JS that we wrote and built with Babel, and even JS that came out of webpack. This way we don't have to figure out how to jam a minifier into three places, and it also means that we might be able to do some better minification (eg. by minifying pre-bundled source where we are more likely to be able to detect useful amounts of dead code etc). Note that this also helps "future proof" us a little bit for the arrival of Bundler v3 or v4 or whatever it ends up being called, because the approach can be applied there as well with few or no modifications.

Sub-tasks:

  • Try this out on other modules.
  • Actually write out the changed files.
  • Investigate errors to be sure they are all benign like I think they are.
  • Tweak Terser settings to strike right balance of aggressive/small and safe/stable.
  • More documentation here (like, on why Terser etc).
  • Minify JS in JSP.
  • Check/tweak comment/whitespace handling (for JS in JSP).
  • Add unit tests.
  • Get before and after numbers across DXP to get sense of expected benefit.
  • Update this description with "final" status.

@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 12, 2020

Ok, so I just force-pushed with some updates:

  • Actually writes out files to disk now.
  • Source map support.
  • Turn down logging unless DEBUG is set in the environment.
  • Fixed lint complaints about console.log.

And I checked the errors caused by files that contain non-top-level imports; those really are the only kind of error. Tried it on other modules with some success.

So now I am going to look at doing some minification of JS inside JSP — that might be rather tricky though because the technique we use to run Prettier on JS inside JSP may not transfer across so well (because it is pretty whitespace-sensitive), but I'll investigate and report back what I find here.

wincent added a commit that referenced this pull request Nov 12, 2020
This is a WIP which will need some tweaking before it actually works,
because just as I foreshadowed here:

#233 (comment)

> that might be rather tricky though because the technique we use to run
> Prettier on JS inside JSP may not transfer across so well (because it
> is pretty whitespace-sensitive)

You can see this in the output of accounts-admin-web, were a file like

- src/main/resources/META-INF/resources/account_users_admin/select_account_entry.jsp
  (contents: https://gist.github.com/wincent/af4157dd55eecc3a862dc75cd560f572)

gets mangled to:

- build/node/packageRunBuild/resources/account_users_admin/select_account_entry.jsp
  (contents: https://gist.github.com/wincent/df3db72e83ac0d3e523b9bb7012417d3)

Here's the diff:

https://gist.github.com/wincent/fb57fdd77c3a694405487f38cf1b6a03

It actually doesn't look too shabby at all, but will need some tweaking
to get it totally right.

Notably not handled by this approach are sneaky JSP files that contain
JS outside of `<script>` (or `<aui:script>`) tags. For example:

- JSP: https://github.com/liferay/liferay-portal/blob/510836e72b25d47d8e7095d60506bfc34b104769/modules/apps/frontend-js/frontend-js-web/src/main/resources/META-INF/resources/liferay/available_languages.jsp
- Which is exposed sneakily here, as far as I can tell:
  https://github.com/liferay/liferay-portal/blob/510836e72b25d47d8e7095d60506bfc34b104769/portal-web/docroot/html/common/themes/top_js.jspf#L315
@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 12, 2020

Added a (WIP) commit that formats JS in JSP. You can see this in the output of accounts-admin-web, were a file like src/main/resources/META-INF/resources/account_users_admin/select_account_entry.jsp gets mangled to build/node/packageRunBuild/resources/account_users_admin/select_account_entry.jsp (edit: that path isn't quite right, but you can still see what the contents look like if you click on the link).

Here's the diff; it actually doesn't look too shabby at all, but will need some tweaking to get it totally right.

Notably not handled by this approach are sneaky JSP files that contain JS outside of <script> (or <aui:script>) tags. For example:

I'll take this up again tomorrow to see if I can polish it up enough to mark this as ready for review.

@jbalsas
Copy link
Copy Markdown
Contributor

jbalsas commented Nov 13, 2020

Hey @wincent, I think this makes sense!

Just to clarify, we're always producing foo.js -> foo.js regardless of wether we're minifying or not, correct? Can't spot a specific setting to rename the files, but just want to make sure it's not a default.

I'd say we can park JSP minification unless you think it's very low-hanging fruit and then figure out whether it's worth it or not.

Do you think we have enough already in the analysis phase to wrap it up and start planning this for real? (It feels like we're already well past that 😂 )

@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 13, 2020

Just to clarify, we're always producing foo.js -> foo.js regardless of wether we're minifying or not, correct? Can't spot a specific setting to rename the files, but just want to make sure it's not a default.

We overwrite all existing .js files under build in place, except ones which already have the -min.js or .min.js suffixes (this matches the heuristic used on the server at the moment). That's what makes this change so minimal, and means it handles our own JS source, source from node_modules that has gone through arbitrary transformation by the bundler (v2 or v3), or through webpack.

I'd say we can park JSP minification unless you think it's very low-hanging fruit and then figure out whether it's worth it or not.

So I added another commit polishing that up. I'd say it's pretty "solid" at this point. I see one sort-keys lint failure so I am going to fix that up and push a commit for that too.

Do you think we have enough already in the analysis phase to wrap it up and start planning this for real? (It feels like we're already well past that 😂 )

Indeed we are, but the thing with abstract stuff like this is that it is much easier to discuss when you have a concrete artifact. Questions like "is it really going to be that much simpler to do a single build rather than a dual build", or "how many bytes is this actually going to save us", or "is it worth the effort of minifying code in JSP" all become trivially easy to answer at this point. To that effect I think on Monday I am going to run this over all of DXP to get some before-and-after numbers, and I'll do some quick smoke testing to show that DXP has a chance of running properly after a fully minified ant all.

And after that I don't know what planning is left to do.

@wincent wincent marked this pull request as ready for review November 13, 2020 13:36
@jbalsas
Copy link
Copy Markdown
Contributor

jbalsas commented Nov 13, 2020

And after that I don't know what planning is left to do.

Exactly 😂

[...] the thing with abstract stuff like this is that it is much easier to discuss when you have a concrete artifact

Yeah, I think we're done with analysis the moment we make an educated guess as to which direction we wanted to push for and work on this in npm-scripts rather than doing a quick and dirty test on DXP.

If (as many times happens) our assumptions are proven wrong, then we simply step back and approach the problem differently.

@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 16, 2020

Cut a v34.1.0-pre.0 in order to test this and gather some metrics after a full ant all in liferay-portal (created LPS-123515 for that). I expect some things to break because the default minification is likely a bit more aggressive than what we get with Google's Closure compiler running in "simple" mode, so we may have to tweak some settings to dumb it down a bit.

@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 16, 2020

Was going to rebase this on master because of the merge conflicts, but it seems the yarn.lock is bogus and should be fixed separately (ie. running yarn on master creates a large diff, and I think we might have a problem with our tags — one of the deps it adds is @liferay/[email protected], but we only have a tag for @liferay/[email protected]).

So I'll just push what I have over this stale history; this change kind of blows my mind:


chore(npm-scripts): make minification more conservative

Based on testing across the liferay-portal repo, the property mangling needs to be turned off because it does some IMO surprising things. For example, in:

https://github.com/liferay/liferay-portal/blob/c74cbb3487428c54ae2122c205af3c954e0e01a3/modules/apps/frontend-js/frontend-js-aui-web/src/main/resources/META-INF/resources/liferay/modules.js#L18-L21

This:

(function () {
   var LiferayAUI = Liferay.AUI;

   var COMBINE = LiferayAUI.getCombine();

gets mangled to:

!function(){var e = Liferay.AUI,a=e.i()

ie. global Liferay.AUI gets preserved (good), but a call to its getCombine() method gets unfathomably rewritten to i(). No idea why it would think it's legit to do that, but whatever, we can turn off that kind of mangling with the following effects:

  • With unwanted mangling (ie. prior to this commit):

    Before size:       616616
    After size:        201246
    Delta:             415370
    
  • With mangle: false (ie. no mangling at all):

    Before size:       616616
    After size:        353013
    Delta:             263603
    
  • With mangle: {properties: false} (ie. this commit):

    Before size:       616616
    After size:        266414
    Delta:             350202
    

So we lose a bit of minification but not all of it (ie. instead of trimming 405K, we trim 341K, which is not quite as bad as if we'd turned off all mangling, which would mean trimming only 257K).

The other step in a conservative direction that I'm taking in this commit is turning off some other renames that might cause problems when minifying JSP. I haven't seen any evidence that this is needed yet, but am erring on the side of caution.

wincent added a commit that referenced this pull request Nov 16, 2020
This should ensure that we don't run into the kind of issue mentioned
here:

    #233 (comment)

Note that `--frozen-lockfile` is supposed to take care of this for us,
but it is a known issue that it doesn't work properly in monorepos:

    yarnpkg/yarn#5840

There is a fix for it:

    yarnpkg/yarn#6554

But the issue is nearly two years old and the PR is almost as old. Maintainer replies here:

    yarnpkg/yarn#6554 (comment)

that:

> The change appears sound, but we're currently working on the v2
> (scheduled before the end of the year) and I'm somewhat worried about
> introducing subtle bugs right before releasing the next major (the
> way I see it, the current v1 is, despite its shortcomings, relatively
> stable)."

We face a similar concern in liferay-portal and have a ticket for that:

    https://issues.liferay.com/browse/LPS-110313
wincent added a commit that referenced this pull request Nov 16, 2020
This should ensure that we don't run into the kind of issue mentioned
here:

    #233 (comment)

Note that `--frozen-lockfile` is supposed to take care of this for us,
but it is a known issue that it doesn't work properly in monorepos:

    yarnpkg/yarn#5840

There is a fix for it:

    yarnpkg/yarn#6554

But the issue is nearly two years old and the PR is almost as old. Maintainer replies here:

    yarnpkg/yarn#6554 (comment)

that:

> The change appears sound, but we're currently working on the v2
> (scheduled before the end of the year) and I'm somewhat worried about
> introducing subtle bugs right before releasing the next major (the
> way I see it, the current v1 is, despite its shortcomings, relatively
> stable)."

We face a similar concern in liferay-portal and have a ticket for that:

    https://issues.liferay.com/browse/LPS-110313
These are all independent (they all end with `break`) so we may as well
have them in alphabetical order.

Sorting this before I add another one in commit real soon now.
This implements the first part of the idea described here:

    https://docs.google.com/document/d/1JYSSSVFQlEwy1CRv1ZD6hfql8AzuXTS39qY5HMnvUe4/edit

Namely, if we're not in development mode, we pre-minify JS resources
before they are served. At the moment, I developed this just enough to
get some numbers. Here is what we see in `frontend-js-react-web`, which
is a good example of an OSGi module containing some "own JS" +
dependencies in `node_modules`.

    Summary:
      Files minified:    806
      Files with errors: 169
      Before size:       3561639
      After size:        878708
      Delta:             2682931
      Elapsed:           8.88

Sizes are just raw bytes, ignoring gzip, so the "real" size in a
production environment would be much less, obviously (but so will the
savings).

Lots of files with errors, but at a glance, most of those look legit,
because our bundler will take every file in the graph and AMD wrap it
even if it shouldn't be wrapped (due to config, or whatever), so we wind
up with illegal JS in the JAR that will never get used (like files with
`import` statements inside AMD factory definitions).

The approach is to minify all the JS as a last step in the build
process. This way we cover JS that came in from `yarn install` and the
bundler, JS that we wrote and built with Babel, and even JS that came
out of webpack. This way we don't have to figure out how to jam a
minifier into three places, and it also means that we might be able to
do some better minification (eg. by minifying pre-bundled source where
we are more likely to be able to detect useful amounts of dead code
etc). Note that this also helps "future proof" us a little bit for the
arrival of Bundler v3 or v4 or whatever it ends up being called, because
the approach can be applied there as well with few or no modifications.
This is a WIP which will need some tweaking before it actually works,
because just as I foreshadowed here:

#233 (comment)

> that might be rather tricky though because the technique we use to run
> Prettier on JS inside JSP may not transfer across so well (because it
> is pretty whitespace-sensitive)

You can see this in the output of accounts-admin-web, were a file like

- src/main/resources/META-INF/resources/account_users_admin/select_account_entry.jsp
  (contents: https://gist.github.com/wincent/af4157dd55eecc3a862dc75cd560f572)

gets mangled to:

- build/node/packageRunBuild/resources/account_users_admin/select_account_entry.jsp
  (contents: https://gist.github.com/wincent/df3db72e83ac0d3e523b9bb7012417d3)

Here's the diff:

https://gist.github.com/wincent/fb57fdd77c3a694405487f38cf1b6a03

It actually doesn't look too shabby at all, but will need some tweaking
to get it totally right.

Notably not handled by this approach are sneaky JSP files that contain
JS outside of `<script>` (or `<aui:script>`) tags. For example:

- JSP: https://github.com/liferay/liferay-portal/blob/510836e72b25d47d8e7095d60506bfc34b104769/modules/apps/frontend-js/frontend-js-web/src/main/resources/META-INF/resources/liferay/available_languages.jsp
- Which is exposed sneakily here, as far as I can tell:
  https://github.com/liferay/liferay-portal/blob/510836e72b25d47d8e7095d60506bfc34b104769/portal-web/docroot/html/common/themes/top_js.jspf#L315
This may end up being a throw-away commit — I am not sure whether this
is legit — or I will squash it into the parent before merging.

Yesterday when I tested this there were ".jsp" files in the "build"
folder, which is how I was able to produce this diff showing the
minified JS:

    https://gist.github.com/wincent/fb57fdd77c3a694405487f38cf1b6a03

Well, today after cleaning "build" and "classes", I only have JSP in
the latter. So I am hard-coding this modification in the most horrible
way, but it does work. The minified JS winds up in the JSP files that
you can find in the JAR; in the case of the module that I'm currently
testing, that's:

    build/tmp/jar/com.liferay.account.admin.web-2.0.0.jar

Doubts:

- Is this even remotely kosher?
- Should it be configurable?
- Will modifying files in "classes/" cause trouble (redundant builds
  stale caches) with Gradle or with "deploy fast" mode?
- Made comment-handling more robust.
- Tweaked settings (eg. to turn off mangling).
- Added tests.

Required a bit of refactoring which is hopefully is safe thanks to our
test coverage here.
Based on testing across the liferay-portal repo, the property mangling
needs to be turned off because it does some IMO surprising things. For
example, in:

    https://github.com/liferay/liferay-portal/blob/c74cbb3487428c54ae2122c205af3c954e0e01a3/modules/apps/frontend-js/frontend-js-aui-web/src/main/resources/META-INF/resources/liferay/modules.js#L18-L21

This:

```
(function () {
   var LiferayAUI = Liferay.AUI;

   var COMBINE = LiferayAUI.getCombine();
```

gets mangled to:

```
!function(){var e = Liferay.AUI,a=e.i()
```

ie. global `Liferay.AUI` gets preserved (good), but a call to its
`getCombine()` method gets unfathomably rewritten to `i()`. No idea why
it would think it's legit to do that, but whatever, we can turn off that
kind of mangling with the following effects:

-   With unwanted mangling (ie. prior to this commit):

    Before size:       616616
    After size:        201246
    Delta:             415370

-   With `mangle: false` (ie. no mangling at all):

    Before size:       616616
    After size:        353013
    Delta:             263603

-   With `mangle: {properties: false}` (ie. this commit):

    Before size:       616616
    After size:        266414
    Delta:             350202

So we lose a bit of minification but not all of it (ie. instead of
trimming 405K, we trim 341K, which is not quite as bad as if we'd turned
off all mangling, which would mean trimming only 257K).

The other step in a conservative direction that I'm taking in this
commit is turning off some other renames that might cause problems when
minifying JSP. I haven't seen any evidence that this is needed yet, but
am erring on the side of caution.
@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 24, 2020

Resolved merge conflicts and force-pushed; no other changes.

@jbalsas
Copy link
Copy Markdown
Contributor

jbalsas commented Nov 24, 2020

Screen Shot 2020-11-24 at 11 14 01

nuffsaid

@jbalsas
Copy link
Copy Markdown
Contributor

jbalsas commented Nov 24, 2020

Are we going with minified JS in JSP, then?

}

if (process.env.NODE_ENV !== 'development') {
await minify();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was wondering where in the process would CSS be minified... Since terser can only minify JS, where do you see CSS build pipeline going?

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.

I focussed specifically on JS because that's what the LPS called for, but was thinking that once @bryceosterhaus's Dart Sass stuff has gone in, we tack on minification to that — depending on how long that work takes, we could look at doing it sooner, but I figured it was the path of least churn to wait.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sounds good!

@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 24, 2020

Are we going with minified JS in JSP, then?

I'm testing in DXP again today. If it goes poorly, we can rip out the minifying-in-JSP to expedite this. If it goes well, we may as well use it.

@jbalsas
Copy link
Copy Markdown
Contributor

jbalsas commented Nov 24, 2020

I'm testing in DXP again today. If it goes poorly, we can rip out the minifying-in-JSP to expedite this. If it goes well, we may as well use it.

Here's to it going well!! 🥂

@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 24, 2020

Ok, summarizing my testing.

I think this breaks little or nothing — screenshot shows a minified Clay file, but similar results for other node modules, and DXP-internal modules:

Screenshot 2020-11-24 -155510-2J2R6IJt@2x

Also all the tests are green over on my fork:


✔️ ci:test:stable - 9 out of 9 jobs passed

✔️ ci:test:relevant - 20 out of 20 jobs passed in 2 hours 54 minutes

Click here for more details.

Base Branch:

Branch Name: master
Branch GIT ID: cf5f0b9de37165381f866420408e6e7e7e014939

Copied in Private Modules Branch:

Branch Name: master-private
Branch GIT ID: 8d22a791300569a6c92e7b9152e6ae1c6bdc863a

ci:test:stable - 9 out of 9 jobs PASSED
9 Successful Jobs:
ci:test:relevant - 20 out of 20 jobs PASSED
20 Successful Jobs:
For more details click here.

But some things are escaping minification; I'll look into these to see if I can discover a pattern:

Screenshot 2020-11-24 -155624-DFPWImrH@2x

And source maps don't seem to work. They are detected, but I don't see the original source:

Screenshot 2020-11-24 -155709-NJYDwLuz@2x

Finally — minification in JSP didn't happen, because of ordering and/or caching issues. While it worked previously in my per-module test deployments, it doesn't seem to have taken effect globally during ant all:

Screenshot 2020-11-24 -160352-J4GyXuxG@2x

That's corresponds to these lines from product-navigation-site-administration, which I naïvely expected to have been minified — but when I look in there, I see that there is no package.json in that module, so liferay-npm-scripts doesn't get the chance to do its thing there.

More concerning though, is that it's not working for modules like this file in account-admin-web, which doesn have a package.json that calls liferay-npm-scripts build.

If I run yarn run build in that module, it does work; ie. JS gets minified to:

<aui:script use="liferay-search-container">var searchContainer=Liferay.SearchContainer.get("<portlet:namespace />accountUsers");searchContainer.on("rowToggled",(function(event){var selectedItems=event.elements.allSelectedElements,result={};selectedItems.isEmpty()||(result={data:{value:selectedItems.get("value").join(",")}}),Liferay.Util.getOpener().Liferay.fire("<%= HtmlUtil.escapeJS(eventName) %>",result)})),Liferay.Util.selectEntityHandler("#<portlet:namespace />selectAccountUser","<%= HtmlUtil.escapeJS(eventName) %>");</aui:script>

and I can deploy that and see it working (ie. see the console.log in the minified source):

  • ant all = no minification

  • yarn run build = minification works

  • gradlew clean deploy -a = no minification

  • gradlew deploy -a = gradlew skips yarn build

    Task :apps:account:account-admin-web:packageRunBuild UP-TO-DATE

  • gradlew clean deploy -a = gradlew skips yarn build again

    Task :apps:account:account-admin-web:packageRunBuild FROM-CACHE

  • yarn run build && gradlew deploy -a = gradlew does yarn build again, and minification works

    Task :apps:account:account-admin-web:packageRunBuild
    $ liferay-npm-scripts build
    Minification summary:
    Files processed: 73
    Files with errors: 0
    Before size: 193469
    After size: 171197
    Delta: 22272
    Elapsed: 0.63

    but inspecting the JAR at build/tmp/jar/com.liferay.account.admin.web-2.0.0.jar shows it to contain unminified JS.

So I'll keep poking around a bit to see if I can get the JSP thing working, but I suspect that the fiendish devilry of Gradle's dependency analysis and caching means that it is probably going to fall into the "not worth it category".

@jbalsas
Copy link
Copy Markdown
Contributor

jbalsas commented Nov 24, 2020

But some things are escaping minification; I'll look into these to see if I can discover a pattern:

I think the AUI ones are expected since they're probably simply moved over in their final form from either a maven artefact or an npm dependency into to the build without passing through src and probably skipping the whole build process. I'd expect other dependencies to go to through a similar process.

More concerning though, is that it's not working for modules like this file in account-admin-web, which doesn have a package.json that calls liferay-npm-scripts build.

I think that's also what @bryceosterhaus saw in the analysis for LPS-123287 - Analyze Sass compilation pipeline

Other modules that use BuildCSS but not npm-scripts, migrate those to use npm-scripts.

@wincent
Copy link
Copy Markdown
Contributor Author

wincent commented Nov 24, 2020

FWIW I asked the build wizards over in #build about this, but is mostly a theoretical exercise at this point. My testing shows that the tasks run in this order, basically:

gradlew compileJava -a # puts 12 directories, 1 file in build/, and 35 directories, 97 files into classes/ — no JSP yet
gradlew packageRunBuild -a # would minify JSP, but it's not there yet
gradlew processResources -a # puts 54 directories, 158 files in build/, 61 directories, 256 files into classes/ - JSP is now in there
gradlew classes -a # doesn't do anything: > Task :apps:account:account-admin-web:classes UP-TO-DATE

Full text of my question for posterity:


i'm trying to figure out if there's a nice way to insert some additional processing into the JSP build process, and I'm wondering if somebody wise in the ways of our gradle tasks can confirm my understanding of how it works

specifically, the high-level goal is to extract JS from <script> (and <aui:script>) tags in JSP files, pre-minify it, and inject it back in. i have a proof of concept that does that in a hacky way during the packageRunBuild task by overwriting JSP files under classes/

now, this works as a demo but not in practice because the actual order the tasks run is something like this:

compileJava - Compiles main Java source.
packageRunBuild - Runs the "build" package.json script.
processResources - Processes main resources.
classes - Assembles main classes.

ie. compileJava sticks a few bits and pieces in build/ and classes/, but doesn't put the JSP in there yet, then runs packageRunBuild, which would do JS-in-JSP pre-minification if there were any JSP files in classes/ (but there aren't yet), then runs processResources which is what actually shoves the JSP in there

so I guess my questions are these:

  1. is there a better (non-hacky) way to "pre-process" or "post-process" the JSP files, ideally something we could do from packageRunBuild without introducing another task
  2. failing that, would it be feasible to change the dependency relationship so that packageRunBuild runs after processResources (ie. when the JSP files are there to operate on)
  3. and failing that, if we were to add another task as a post-processing step, how difficult is that to do and would the "juice be worth the squeeze"? so to speak

@wincent wincent merged commit ed8a348 into master Nov 25, 2020
@wincent wincent deleted the wincent/minify branch November 25, 2020 14:52
wincent added a commit that referenced this pull request Dec 18, 2020
docs: describe team repo sync script
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants