项目作者: dsathyakumar

项目描述 :
A Babel codemod that acts as a build / compile time optimizer for Lasso JS. Gives Lasso JS some extra arms.
高级语言: JavaScript
项目地址: git://github.com/dsathyakumar/lasso-optimizer.git
创建时间: 2019-10-09T19:43:30Z
项目社区:https://github.com/dsathyakumar/lasso-optimizer

开源协议:

下载


lasso-optimizer

A Babel CodeMod plugin that acts as a build / compile time optimizer for Lasso JS. Gives Lasso JS some extra arms.

What is this?

  • Lasso JS produces output bundles similar to the NODEJS common-js style syntax on the browser.
  • This is an optimizer stage plugin & a Babel CodeMod for Lasso JS, that is applied on the final aggregated output of Lasso JS.
  • It performs code transformations
  • It cannot be used as a transform or as a usual JS plugin in the list of Lasso plugins

Why is this needed?

  • This plugin helps in further optimizing Lasso JS output bundles under certain conditions, while resolving modules, require.resolve, require, conditional requires & circular dependencies.
  • Currrently, Lasso JS inlines the filepaths of modules like
  1. $_mod.def("/marko$4.17.3/components/runtime", function (require, exports, module, __filename, __dirname) {
  2. const f_55 = require('/marko$4.17.3/components/index-browser.marko');
  3. exports.a = 45;
  4. exports.func = () => {};
  5. module.exports = () => {
  6. };
  7. });
  8. $_mod_gh_fe.remap("/marko$4.17.3/components", "/marko$4.17.3/components-browser.marko");
  9. $_mod_gh_fe.installed("globalheaderfrontend$25.1.0", "marko", "4.17.3");
  10. $_mod_gh_fe.remap("/marko$4.17.3/src/runtime/components/index", "/marko$4.17.3/src/runtime/components/index-browser");
  • While they provide a mirror representation of your projects file system, this tends to be of an overhead & bloat for projects.
  • Further, these are resolved on the browser by Lasso Modules Client Side Run Time that performs a Node JS style module resolution.
  • Inlined filepaths & the client side runtime take upto >30KB-200KB in your ungzipped output bundle & upto 5KB-20KB in your gzipped response.
  • As JS parse times are impacted by bundle size bloats, this helps optimize the bundle for it.

What does this do?

  • This plugin applies an output transformation on the final aggregated code / bundle.
  • It attempts to resolve all filepaths and module dependencies at build time
  • It transform modules into simple function expressions
  1. $_mod.def("/marko$4.17.3/components/runtime", function (require, exports, module, __filename, __dirname) {
  2. // code here
  3. });
  4. $_mod.run("/marko$4.17.3/components/runtime");
  5. $_mod_gh_fe.remap("/marko$4.17.3/components", "/marko$4.17.3/components-browser.marko");
  6. $_mod_gh_fe.installed("globalheaderfrontend$25.1.0", "marko", "4.17.3");
  7. $_mod_gh_fe.main("/process$4.17.3", "src/runtime/components/index-browser");

to

  1. function __marko_4_17_3__components__runtime(require, exports, module, __filename, __dirname) {
  2. /* __marko_4_17_3__components_index_browser__marko is already available in toplevel scope */
  3. const f_55 = require(__marko_4_17_3__components_index_browser__marko);
  4. exports.a = 45;
  5. exports.func = () => {};
  6. module.exports = () => {
  7. };
  8. }
  9. run(__marko_4_17_3__components__runtime);
  • The .remap, .installed, .main, .run, .builtin, resolve, require, def are all resolved at build / asset bundling phase.
  • On the browser, the bundle doesn’t have to resolve these anymore.
  • By doing this, it gets rid of the Lasso Modules Client Side Run Time & uses a miniature version of it.

What do you get by doing this?

  • All inline file paths are resolved before runtime.
  • Check out the /sample folder for the input and output. The input is a bundle of size 404KB and copy paste the output bundle into https://try.terser.org/ with options as
  1. {
  2. toplevel: true,
  3. compress: {
  4. toplevel: true
  5. },
  6. mangle: {
  7. toplevel: true
  8. },
  9. output: {},
  10. parse: {},
  11. rename: {},
  12. }

The minified output will now be 250KB.

Usage

  • This cannot be applied as transform in the Lasso config or be used as a plugin.
  • This cannot also resolve dynamic require calls where the argument of require is not a String but an identifier resolved dynamically
  • The following Lasso Config is a sample where the output would be bundled for production.
    1. {
    2. "plugins": [
    3. "lasso-less",
    4. "lasso-autoprefixer",
    5. "lasso-marko",
    6. "lasso-minify-transpile-inline",
    7. "rollup-plugin-lasso",
    8. {
    9. "plugin": "lasso-inline-slots",
    10. "config": {
    11. "inlineSlots": [
    12. "inline"
    13. ]
    14. }
    15. }
    16. ],
    17. "require": {
    18. "lastSlot": "inline",
    19. "transforms": [
    20. "lasso-babel-env"
    21. ]
    22. },
    23. "outputDir": "static",
    24. "minify": true,
    25. "minifyInlineOnly": true,
    26. "bundlingEnabled": true,
    27. "resolveCssUrls": true,
    28. "noConflict": "gh-fe",
    29. "cacheProfile": "production"
    30. }

Now, the above output would cause Lasso to dump the final minfied output bundled under
${PROJECT_DIR}/static.

  1. const { readFileSync, writeFileSync } = require('fs');
  2. const { optimizeSingleSourceFile } = require('lasso-optimizer');
  3. const code = readFileSync('static/my-awesome-bundle.js', 'utf8');
  4. const result = optimizeSingleSourceFile(code);
  5. writeFileSync('static/optimized-bundle.js', 'utf8');
  6. // now proceed to upload to resource server.