Skip to content

Commit

Permalink
[BUGFIX lts] Compile Ember dynamically in consuming applications
Browse files Browse the repository at this point in the history
This PR sets up Ember to do a two phase build:

* **Phase 1, prepublish:** Run Typescript and Rollup on the main Ember
  packages, and strip out canary-features. Publish these packages, along
  with the dependencies for Ember, in the `dist/` folder.

* **Phase 2, in addon:** Run Babel transpilation using the consumer's
  `ember-cli-babel` and Babel configuration on the dist packages and
  dependencies, and bundle up the final `ember.js` file to serve to
  apps. This also includes `debug` flags and, in theory, svelting.

Two major changes that will occur because of this:

1. We will no longer be distributing `ember.prod.js`, `ember.debug.js`,
   `ember.min.js`, or `ember-testing.js`. These files existing may be
   something that people rely on, and the packages that _are_
   distributed aren't quite ready to build in a "normal" way, using
   webpack or another bundler.
2. We will no longer be _building_ `ember.prod.js`, `ember.min.js`, or
   `ember.debug.js` at all, only a single `ember.js` file. We no longer
   need separate builds, because the environment settings of the build
   will handle the differences for us.

We _are_ continuing to distribute a pre-built version of the `ember.js`
and `ember-testing.js` files. These are used only in the case where the
build targets match the default development build targets for Ember
apps, providing a small optimization for users' dev workflow.

Unfortunately, until we disentangle `ember-cli` from the implementation
details of `ember-source` we cannot convert Ember to _build_ like a
normal addon locally. Using the `EmberAddon` class blows up in many
small ways.
  • Loading branch information
Chris Garrett committed Aug 2, 2019
1 parent a1b5a6b commit de69708
Show file tree
Hide file tree
Showing 34 changed files with 528 additions and 680 deletions.
30 changes: 23 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,42 @@ install:
jobs:
include:
- stage: basic test
env: TEST_SUITE=each-package-tests
env: TEST_SUITE=each-package
script:
- yarn ember build
- yarn test

- name: Linting
script:
- yarn lint

- stage: additional tests
- stage: Additional Tests
name: Browserstack Tests (Safari, Edge, IE11)
env: SHOULD_TRANSPILE=true
script:
- yarn ember build -prod
- yarn ember build
- yarn test:browserstack

- env:
- TEST_SUITE=built-tests
- EMBER_ENV=production
- name: Development (All Tests + Canary Features)
script:
- yarn ember build
- yarn test

- env: TEST_SUITE=old-jquery-and-extend-prototypes
- name: Production (All Tests + Canary Features)
env: SHOULD_TRANSPILE=true
script:
- yarn ember build -prod
- yarn test

- name: Old Jquery and Extend Prototypes
env: TEST_SUITE=old-jquery-and-extend-prototypes
script:
- yarn ember build
- yarn test

- name: Node.js Tests
node_js: "8"
env: SHOULD_TRANSPILE=true
script:
- yarn ember build -prod
- yarn test:node
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,15 @@ When you submit your PR (or later change that code), a Travis build will automat

Within the Travis build, you can see that we (currently) run six different test suites.

* The `each-package-tests` test suite is closest to what you normally run locally on your machine.
* The `each-package` test suite is closest to what you normally run locally on your machine.
* The `build-tests EMBER_ENV=production...` test suite runs tests against a production build.
* The `browserstack` test suite runs tests against various supported browsers.

## Common Travis CI Build Issues

### Production Build Failures

If your build is failing on the 'production' suite, you may be relying on a debug-only function that does not even exist in a production build (`Ember.warn`, `Ember.deprecate`, `Ember.assert`, etc.). These will pass on the 'each-package-tests' suite (and locally) because those functions are present in development builds.
If your build is failing on the 'production' suite, you may be relying on a debug-only function that does not even exist in a production build (`Ember.warn`, `Ember.deprecate`, `Ember.assert`, etc.). These will pass on the 'each-package' suite (and locally) because those functions are present in development builds.

There are helpers for many of these functions, which will resolve this for you: `expectDeprecation`, `expectAssertion`, etc. Please use these helpers when dealing with these functions.

Expand Down
33 changes: 19 additions & 14 deletions bin/run-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'use strict';

const chalk = require('chalk');
const runInSequence = require('../lib/run-in-sequence');
const RSVP = require('rsvp');
const path = require('path');

const finalhandler = require('finalhandler');
Expand Down Expand Up @@ -79,15 +79,9 @@ function generateEachPackageTests() {
.forEach(generateTestsFor);
}

function generateBuiltTests() {
function generateStandardTests() {
testFunctions.push(() => run(''));
testFunctions.push(() => run('dist=min&prod=true'));
testFunctions.push(() => run('dist=prod&prod=true'));
testFunctions.push(() => run('enableoptionalfeatures=true&dist=prod&prod=true'));
testFunctions.push(() => run('legacy=true'));
testFunctions.push(() => run('legacy=true&dist=min&prod=true'));
testFunctions.push(() => run('legacy=true&dist=prod&prod=true'));
testFunctions.push(() => run('legacy=true&enableoptionalfeatures=true&dist=prod&prod=true'));
testFunctions.push(() => run('enableoptionalfeatures=true'));
}

function generateOldJQueryTests() {
Expand All @@ -101,6 +95,18 @@ function generateExtendPrototypeTests() {
testFunctions.push(() => run('extendprototypes=true&enableoptionalfeatures=true'));
}

function runInSequence(tasks) {
var length = tasks.length;
var current = RSVP.Promise.resolve();
var results = new Array(length);

for (var i = 0; i < length; ++i) {
current = results[i] = current.then(tasks[i]);
}

return RSVP.Promise.all(results);
}

function runAndExit() {
runInSequence(testFunctions)
.then(function() {
Expand All @@ -121,9 +127,9 @@ switch (process.env.TEST_SUITE) {
generateTestsFor(p);
runAndExit();
break;
case 'built-tests':
console.log('suite: built-tests');
generateBuiltTests();
case 'each-package':
console.log('suite: optional-features');
generateEachPackageTests();
runAndExit();
break;
case 'old-jquery-and-extend-prototypes':
Expand All @@ -134,14 +140,13 @@ switch (process.env.TEST_SUITE) {
break;
case 'all':
console.log('suite: all');
generateBuiltTests();
generateOldJQueryTests();
generateExtendPrototypeTests();
generateEachPackageTests();
runAndExit();
break;
default:
console.log('suite: default (generate each package)');
generateEachPackageTests();
generateStandardTests();
runAndExit();
}
37 changes: 0 additions & 37 deletions broccoli/bootstrap-modules.js

This file was deleted.

33 changes: 33 additions & 0 deletions broccoli/canary-features.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

const Babel = require('broccoli-babel-transpiler');
const FEATURES = require('./features');

module.exports = function canaryFeatures(tree) {
let plugins = [
[
'debug-macros',
{
flags: [
{
source: '@ember/canary-features',
flags: Object.assign(
// explicit list of additional exports within @ember/canary-features
// without adding this (with a null value) an error is thrown during
// the feature replacement process (e.g. XYZ is not a supported flag)
{
FEATURES: null,
DEFAULT_FEATURES: null,
isEnabled: null,
},
FEATURES
),
},
],
},
'debug-macros:canary-flags',
],
];

return new Babel(tree, { plugins });
};
32 changes: 0 additions & 32 deletions broccoli/concat-bundle.js

This file was deleted.

35 changes: 2 additions & 33 deletions broccoli/debug-macros.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,12 @@
'use strict';

const Babel = require('broccoli-babel-transpiler');
const FEATURES = require('./features');
const buildDebugMacroPlugin = require('../lib/build-debug-macro-plugin');

module.exports = function debugMacros(tree, environment) {
let isDebug = environment !== 'production';

let plugins = [
[
'debug-macros',
{
debugTools: {
source: '@ember/debug',
assertPredicateIndex: 1,
isDebug,
},
externalizeHelpers: {
module: true,
},
flags: [
{ source: '@glimmer/env', flags: { DEBUG: isDebug } },
{
source: '@ember/canary-features',
flags: Object.assign(
// explicit list of additional exports within @ember/canary-features
// without adding this (with a null value) an error is thrown during
// the feature replacement process (e.g. XYZ is not a supported flag)
{
FEATURES: null,
DEFAULT_FEATURES: null,
isEnabled: null,
},
FEATURES
),
},
],
},
],
];
let plugins = [buildDebugMacroPlugin(isDebug)];

return new Babel(tree, { plugins });
};
Loading

0 comments on commit de69708

Please sign in to comment.