aurelia / bootstrapper

Sets up the default configuration for the aurelia framework and gets you up and running quick and easy.
MIT License
75 stars 34 forks source link

Require like loader not possible #68

Closed fragsalat closed 6 years ago

fragsalat commented 6 years ago

What: Removing the version check in this line to be able to use alameda instead of requriejs

Why: I would like to use requirejs like module loader as they seem to improve my application performance. The creators of RequireJS created alameda.js and almond.js which is using implemented like requirejs. When bundling all files and not using any asynchronous plugins almond could be used to improve the performance. I would like to use alameda as I have asynchronous loader plugins but I'm targeting only modern browsers. The problem is that both loaders doesn't have the version property.

As I don't know why exactly you added the check for an existing version I would ask you if this even does make sense? I also could create a custom loader to support it but wanted to ask here first. PS: Sry for removing the template but it's not a bug and only maybe a feature request.

EisenbergEffect commented 6 years ago

I don't think that check can be removed without breaking browser support. I think that was a check related to detecting a Node-based require vs. a browser-based one. @jods4 may remember if that's correct. We're definitely open to improving this but we need to be sure not to break the standard browser-based or node-based scenarios.

fragsalat commented 6 years ago

Just an idea would be to nut check the host.require.version but check for host.define. This should not exist on nodejs and if this is not precise enough host.define.amd is set on all requirejs versions and could be used.

Cajon: https://github.com/requirejs/cajon/blob/master/cajon.js#L2384 RequireJS: https://github.com/requirejs/requirejs/blob/master/require.js#L2128 Alameda: https://github.com/requirejs/alameda/blob/master/alameda.js#L1261 Almond: https://github.com/requirejs/almond/blob/master/almond.js#L431

fragsalat commented 6 years ago

@EisenbergEffect I know that you already requested a performance comparison of requirejs and alameda on the alameda repo. I've just done a simple one now to put some numbers behind my intend to use alameda. I just created two clean projects based on requirejs. In one project I installed alameda and added a version property in the node module to get it running.

Setup: Name: aurelia-alameda Platform: Web Bundler: Aurelia-CLI Loader: RequireJS Transpiler: Babel Markup Processor: None CSS Processor: None Unit Test Runner: None Integration Test Runner: None Editor: WebStorm

About the test To test the performance I've already created half year ago for my own project an e2e test based on protractor, jasmine and headless chrome. The jasmine tests iterate a certain time and in each iteration a browser is spawned, then the page is loaded and time till a certain selector is in dom is measured and the browser is destroyed again. To test the performance I had 50 iterations so 50 load times to build an average on. At the end I just take the average time. Important is that the browser is started in headless to prevent rendering, browser start and other side tasks corrupting the real code execution time.

Result The result is that the basic app with alameda loaded 100ms faster. Alameda average: 277.1ms, Requirejs average: 376.02ms I repeated the tests several times and got the same results. I am actually very impressed of this result as this is a very small application and still could improve that much. If we really manage to allow this I would also propose to at least add this option to the documentation and maybe also to the cli.

Log for alameda:
Starting 'clear'...
Finished 'clear'
Starting 'buildE2E'...
Finished 'buildE2E'
Starting 'wdUpdate'...
[12:46:10] I/update - selenium standalone: file exists /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.14.0.jar
[12:46:10] I/update - selenium standalone: selenium-server-standalone-3.14.0.jar up to date
[12:46:10] I/update - chromedriver: file exists /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.43.zip
[12:46:10] I/update - chromedriver: unzipping chromedriver_2.43.zip
[12:46:10] I/update - chromedriver: setting permissions to 0755 for /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.43
[12:46:10] I/update - chromedriver: chromedriver_2.43 up to date
[12:46:10] I/update - geckodriver: file exists /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.23.0.tar.gz
[12:46:10] I/update - geckodriver: unzipping geckodriver-v0.23.0.tar.gz
[12:46:10] I/update - geckodriver: setting permissions to 0755 for /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.23.0
[12:46:10] I/update - geckodriver: geckodriver-v0.23.0 up to date
Finished 'wdUpdate'
Starting 'e2e'...
[12:46:10] I/launcher - Running 1 instances of WebDriver
[12:46:10] I/local - Starting selenium standalone server...
[12:46:11] I/local - Selenium standalone server started at http://10.160.52.216:52107/wd/hub
Started
12:46:12.627 Starting tests
12:46:12.628   Suite Performance Test
12:46:12.630     Spec HomePage
12:46:13.221       measured 0 of 50 with 254ms
12:46:13.801       measured 1 of 50 with 265ms
12:46:14.364       measured 2 of 50 with 260ms
12:46:14.921       measured 3 of 50 with 263ms
12:46:15.490       measured 4 of 50 with 261ms
12:46:16.057       measured 5 of 50 with 283ms
12:46:16.631       measured 6 of 50 with 278ms
12:46:17.168       measured 7 of 50 with 251ms
12:46:17.725       measured 8 of 50 with 265ms
12:46:18.285       measured 9 of 50 with 261ms
12:46:18.932       measured 10 of 50 with 310ms
12:46:19.562       measured 11 of 50 with 298ms
12:46:20.197       measured 12 of 50 with 295ms
12:46:20.773       measured 13 of 50 with 254ms
12:46:21.346       measured 14 of 50 with 290ms
12:46:21.897       measured 15 of 50 with 267ms
12:46:22.451       measured 16 of 50 with 289ms
12:46:23.034       measured 17 of 50 with 278ms
12:46:23.595       measured 18 of 50 with 304ms
12:46:24.108       measured 19 of 50 with 268ms
12:46:24.646       measured 20 of 50 with 278ms
12:46:25.200       measured 21 of 50 with 249ms
12:46:25.831       measured 22 of 50 with 320ms
12:46:26.404       measured 23 of 50 with 273ms
12:46:26.935       measured 24 of 50 with 273ms
12:46:27.452       measured 25 of 50 with 282ms
12:46:27.950       measured 26 of 50 with 241ms
12:46:28.500       measured 27 of 50 with 283ms
12:46:29.125       measured 28 of 50 with 352ms
12:46:29.684       measured 29 of 50 with 262ms
12:46:30.269       measured 30 of 50 with 320ms
12:46:30.850       measured 31 of 50 with 311ms
12:46:31.363       measured 32 of 50 with 283ms
12:46:31.893       measured 33 of 50 with 277ms
12:46:32.461       measured 34 of 50 with 275ms
12:46:33.023       measured 35 of 50 with 268ms
12:46:33.550       measured 36 of 50 with 262ms
12:46:34.097       measured 37 of 50 with 247ms
12:46:34.648       measured 38 of 50 with 249ms
12:46:35.150       measured 39 of 50 with 252ms
12:46:35.687       measured 40 of 50 with 265ms
12:46:36.199       measured 41 of 50 with 281ms
12:46:36.744       measured 42 of 50 with 269ms
12:46:37.274       measured 43 of 50 with 279ms
12:46:37.838       measured 44 of 50 with 289ms
12:46:38.350       measured 45 of 50 with 258ms
12:46:38.866       measured 46 of 50 with 277ms
12:46:39.481       measured 47 of 50 with 282ms
12:46:40.084       measured 48 of 50 with 292ms
12:46:40.682       measured 49 of 50 with 312ms
12:46:40.683       HomePage loaded 50 times
12:46:40.683        Average: 277.1ms
12:46:40.683        Max: 352ms
12:46:40.683        Min: 241ms
.12:46:40.688     Spec passed
12:46:40.688     Spec LoginPage
12:46:40.689     Spec disabled
12:46:40.689     Suite ListPage
12:46:40.689       Spec re- and pre-order
12:46:40.690       Spec disabled
12:46:40.690       Spec seasons HW & FS of current and last year
12:46:40.690       Spec disabled
12:46:40.690       Spec one unit
12:46:40.690       Spec disabled
12:46:40.691     Suite finished
12:46:40.691     Spec PurchaseOrderPage
12:46:40.691     Spec disabled
12:46:40.692   Suite finished

Ran 1 of 6 specs
1 spec, 0 failures
Finished in 28.065 seconds

12:46:40.692 Finished
[12:46:40] I/local - Shutting down selenium standalone server.
[12:46:40] I/launcher - 0 instance(s) of WebDriver still running
[12:46:40] I/launcher - chrome #01 passed
Log for requirejs:
Starting 'clear'...
Finished 'clear'
Starting 'buildE2E'...
Finished 'buildE2E'
Starting 'wdUpdate'...
[12:44:38] I/update - selenium standalone: file exists /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.14.0.jar
[12:44:38] I/update - selenium standalone: selenium-server-standalone-3.14.0.jar up to date
[12:44:38] I/update - chromedriver: file exists /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.43.zip
[12:44:38] I/update - chromedriver: unzipping chromedriver_2.43.zip
[12:44:38] I/update - chromedriver: setting permissions to 0755 for /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.43
[12:44:38] I/update - chromedriver: chromedriver_2.43 up to date
[12:44:38] I/update - geckodriver: file exists /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.23.0.tar.gz
[12:44:38] I/update - geckodriver: unzipping geckodriver-v0.23.0.tar.gz
[12:44:38] I/update - geckodriver: setting permissions to 0755 for /var/www/goodbuy/purchase-orders-frontend/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.23.0
[12:44:38] I/update - geckodriver: geckodriver-v0.23.0 up to date
Finished 'wdUpdate'
Starting 'e2e'...
[12:44:39] I/launcher - Running 1 instances of WebDriver
[12:44:39] I/local - Starting selenium standalone server...
[12:44:39] I/local - Selenium standalone server started at http://10.160.52.216:48972/wd/hub
Started
12:44:40.960 Starting tests
12:44:40.961   Suite Performance Test
12:44:40.962     Spec HomePage
12:44:41.692       measured 0 of 50 with 371ms
12:44:42.402       measured 1 of 50 with 379ms
12:44:43.176       measured 2 of 50 with 400ms
12:44:43.930       measured 3 of 50 with 382ms
12:44:44.589       measured 4 of 50 with 358ms
12:44:45.249       measured 5 of 50 with 385ms
12:44:45.961       measured 6 of 50 with 376ms
12:44:46.617       measured 7 of 50 with 366ms
12:44:47.247       measured 8 of 50 with 356ms
12:44:47.917       measured 9 of 50 with 369ms
12:44:48.545       measured 10 of 50 with 366ms
12:44:49.197       measured 11 of 50 with 363ms
12:44:49.856       measured 12 of 50 with 377ms
12:44:50.511       measured 13 of 50 with 387ms
12:44:51.131       measured 14 of 50 with 364ms
12:44:51.758       measured 15 of 50 with 356ms
12:44:52.462       measured 16 of 50 with 355ms
12:44:53.170       measured 17 of 50 with 393ms
12:44:53.923       measured 18 of 50 with 404ms
12:44:54.602       measured 19 of 50 with 374ms
12:44:55.253       measured 20 of 50 with 347ms
12:44:55.928       measured 21 of 50 with 362ms
12:44:56.739       measured 22 of 50 with 504ms
12:44:57.368       measured 23 of 50 with 377ms
12:44:58.008       measured 24 of 50 with 364ms
12:44:58.601       measured 25 of 50 with 351ms
12:44:59.263       measured 26 of 50 with 352ms
12:44:59.897       measured 27 of 50 with 381ms
12:45:00.525       measured 28 of 50 with 357ms
12:45:01.140       measured 29 of 50 with 353ms
12:45:01.735       measured 30 of 50 with 348ms
12:45:02.336       measured 31 of 50 with 362ms
12:45:02.980       measured 32 of 50 with 352ms
12:45:03.649       measured 33 of 50 with 379ms
12:45:04.301       measured 34 of 50 with 399ms
12:45:04.992       measured 35 of 50 with 408ms
12:45:05.693       measured 36 of 50 with 455ms
12:45:06.368       measured 37 of 50 with 395ms
12:45:07.003       measured 38 of 50 with 377ms
12:45:07.624       measured 39 of 50 with 369ms
12:45:08.225       measured 40 of 50 with 362ms
12:45:08.829       measured 41 of 50 with 381ms
12:45:09.455       measured 42 of 50 with 356ms
12:45:10.102       measured 43 of 50 with 342ms
12:45:10.729       measured 44 of 50 with 360ms
12:45:11.335       measured 45 of 50 with 357ms
12:45:11.955       measured 46 of 50 with 375ms
12:45:12.574       measured 47 of 50 with 394ms
12:45:13.206       measured 48 of 50 with 360ms
12:45:13.886       measured 49 of 50 with 441ms
12:45:13.887       HomePage loaded 50 times
12:45:13.887        Average: 376.02ms
12:45:13.887        Max: 504ms
12:45:13.887        Min: 342ms
.12:45:13.889     Spec passed
12:45:13.890     Spec LoginPage
12:45:13.890     Spec disabled
12:45:13.890     Suite ListPage
12:45:13.890       Spec re- and pre-order
12:45:13.890       Spec disabled
12:45:13.890       Spec seasons HW & FS of current and last year
12:45:13.891       Spec disabled
12:45:13.891       Spec one unit
12:45:13.891       Spec disabled
12:45:13.891     Suite finished
12:45:13.891     Spec PurchaseOrderPage
12:45:13.891     Spec disabled
12:45:13.891   Suite finished

Ran 1 of 6 specs
1 spec, 0 failures
Finished in 32.932 seconds

12:45:13.892 Finished
[12:45:13] I/local - Shutting down selenium standalone server.
[12:45:13] I/launcher - 0 instance(s) of WebDriver still running
[12:45:13] I/launcher - chrome #01 passed
EisenbergEffect commented 6 years ago

@fragsalat Let's cut to the chase....have you been watching the final season of Fairy Tale? 🤣 I haven't started yet but it's top of my list to watch next :)

Ok, back on topic. This looks excellent. Thanks for sharing the perf metrics. When @huochunpeng gets back from vacation, we may even want to look at adding Alameda to the CLI. To be honest, it's been a while and I completely forgot about that option (as well as almond).

Would you be willing to submit a PR with the changes you suggest? I want to have both @jods4 and @bigopon look at it in addition to myself. We just want to be careful in this area :)

fragsalat commented 6 years ago

Hehe I actually just watched the recent 20 episodes of one piece as I made a small break to watch them in a row. :) But I'll may watch it next month :)

To me careful is a very good idea :) I'll read a bit regarding best ways to identify loaders and open a PR. PS: If there would be a comment on that line we would not have to guess XD

EisenbergEffect commented 6 years ago

Apologies for the lack of commenting in that area. We've been thinking about a lot of that as we work on vNext. We're hoping to do a better job there.

Thanks for working on this. Make sure to /cc on the PR when it's ready.

3cp commented 6 years ago

Instead of checking require.version, it should check define.amd, because it is in the spec, and it is what umd wrapper checks.

define.amd is a better indicator of amd loader.

jods4 commented 6 years ago

I can tell how the Webpack part works. It's all about this block: https://github.com/aurelia/bootstrapper/blob/master/src/index.js#L41-L73

if (typeof AURELIA_WEBPACK_2_0 === 'undefined') {
    // Webpack Loader Support
    if (typeof __webpack_require__ !== 'undefined') {
      // Webpack needs the require to be top level to parse the request.
      // However, we don't want to use require or that will cause the Babel
      // transpiler to detect an incorrect dependency.
      const m = __webpack_require__(require.resolve('aurelia-loader-webpack'));
      return Promise.resolve(new m.WebpackLoader());
    }

    // SystemJS Loader Support
    if (host.System && typeof host.System.config === 'function') {
      return host.System.normalize('aurelia-bootstrapper').then(bsn => {
        return host.System.normalize('aurelia-loader-default', bsn);
      }).then(loaderName => {
        return host.System.import(loaderName).then(m => new m.DefaultLoader());
      });
    }

    // AMD Module Loader Support
    if (typeof host.require === 'function' && typeof host.require.version === 'string') {
      return new Promise((resolve, reject) => host.require(['aurelia-loader-default'], m => resolve(new m.DefaultLoader()), reject));
    }

    // Node.js and Electron Support
    if (isNodeLike && typeof module !== 'undefined' && typeof module.require !== 'undefined') {
      // note: we use a scoped module.require() instead of simply require()
      // so that Webpack's parser does not automatically include this loader as a dependency,
      // similarly to the non-global call to System.import() above
      const m = module.require('aurelia-loader-nodejs');
      return Promise.resolve(new m.NodeJsLoader());
    }
} // endif AURELIA_WEBPACK_2_0

The new aurelia-webpack-plugin (v2+) defines AURELIA_WEBPACK_2_0 which means the full block of loader detection goes away during minification. Please ensure any change/new loader detection code goes inside that block.

aurelia-webpack-plugin ensures PLATFORM.Loader is set to aurelia-loader-webpack before startup. That's how it works.

The webpack detection code inside the block above is for aurelia-webpack-plugin@1.x.

Then there's detection of each loader we support, but I don't have good insight about those.

fragsalat commented 6 years ago

Sry. Currently I'm busy with a bigger refactoring. I'll take care of this next week.

fragsalat commented 6 years ago

Just figured out that the default loader as some incompatibilities as well. This line https://github.com/aurelia/loader-default/blob/master/src/index.js#L121 checks for requirejs.s.contexts._.defined to get already defined modules. This seem to be not supported by alameda. So this change wont be enough to fully support other amd loaders. In my case everything seem to work except the dialog service.

EisenbergEffect commented 6 years ago

That particular forEach function is called in rare cases but where the framework occasionally needs to check loaded modules. If there's a way to do that with Alameda somehow, we could add a case, but if there's truly now way, then the noop should be fine. That is only invoked when the framework has an instance or Ctor created directly by a developer and not loaded through the framework...and where it needs to figure out the module id to load the view. Usually, this only happens when using the dialog plugin and providing an object instance directly. In other words, your apps may not even need this and there's likely ways to work around it as well.

EisenbergEffect commented 6 years ago

@fragsalat If you can find a private API for it, we can go ahead and incorporate that here as well. It's what we're doing with require.js already, more or less.

fragsalat commented 6 years ago

Luckily there is also the context but not inside the property "s" require.contexts._.defined

fragsalat commented 6 years ago

I've tested almond as it sounded very promising that it is so lightweight and fast. Sadly it doesn't support asynchronous plugins and therefore not the template loader.

Alameda with the dialog worked for me now.