Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP BREAKING CHANGE: Enforce top-level addon #374

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2017,
ecmaVersion: 2018,
sourceType: 'module'
},
plugins: ['ember'],
Expand All @@ -14,10 +15,11 @@ module.exports = {
Headers: 'off',
Request: 'off',
Response: 'off',
AbortController: 'off',
AbortController: 'off'
},
rules: {
'no-console': ["error", { allow: ['warn'] }]
'ember/no-jquery': 'error',
'no-console': ['error', { allow: ['warn'] }]
},
overrides: [
// TypeScript files
Expand All @@ -43,15 +45,9 @@ module.exports = {
'test/**/*.js',
'tests/dummy/config/**/*.js'
],
excludedFiles: [
'app/**',
'addon-test-support/**',
'addon/**',
'tests/dummy/app/**'
],
excludedFiles: ['app/**', 'addon-test-support/**', 'addon/**', 'tests/dummy/app/**'],
parserOptions: {
sourceType: 'script',
ecmaVersion: 2015
sourceType: 'script'
},
env: {
browser: false,
Expand All @@ -64,11 +60,9 @@ module.exports = {
},
// node tests
{
files: [
'test/**/*.js',
],
files: ['test/**/*.js'],
env: {
mocha: true,
mocha: true
},
rules: {
'node/no-unpublished-require': 'off',
Expand Down
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ language: node_js
node_js:
# we recommend testing addons with the same minimum supported node version as Ember CLI
# so that your addon works for all apps
- "6"
- "8"

addons:
chrome: stable
Expand Down Expand Up @@ -41,8 +41,9 @@ jobs:
# we recommend new addons test the current and previous LTS
# as well as latest stable release (bonus points to beta/canary)
- stage: "Additional Tests"
env: EMBER_TRY_SCENARIO=ember-lts-2.16
- env: EMBER_TRY_SCENARIO=ember-lts-2.18
env: EMBER_TRY_SCENARIO=ember-lts-3.4
- env: EMBER_TRY_SCENARIO=ember-lts-3.8
- env: EMBER_TRY_SCENARIO=ember-lts-3.12
- env: EMBER_TRY_SCENARIO=ember-release
- env: EMBER_TRY_SCENARIO=ember-beta
- env: EMBER_TRY_SCENARIO=ember-canary
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ HTML5 [fetch](https://fetch.spec.whatwg.org) polyfill from [github](https://gith

* `ember install ember-fetch`

ember-fetch requries ember-cli 2.13 or above.

## Usage

```js
Expand Down Expand Up @@ -66,6 +68,10 @@ export default DS.RESTAdapter.extend(AdapterFetch, {
});
```

### Top Level Addon
For addon authors, `ember-fetch` should also be listed as a [peer dependency](https://docs.npmjs.com/files/package.json#peerdependencies),
host app needs to install `ember-fetch` at top level.

### Use with Fastboot
#### ajax-service
Currently, Fastboot supplies its own server-side ajax functionality, and including `ember-fetch` and the `adapter-fetch` mixin in a Fastboot app will not work without some modifications. To allow the `node-fetch` polyfill that is included with this addon to make your API calls, you must add an initializer to the consuming app's `fastboot` directory that overrides the one Fastboot utilizes to inject its own ajax.
Expand Down Expand Up @@ -94,10 +100,6 @@ export default {
However, `ember-fetch` grabs the `protocol` and `host` info from fastboot request after the `instance-initializes`.
This allows you to make a relative URL request unless the app is not initialized, e.g. `initializers` and `app.js`.

#### top-level addon
For addon authors, if the addon supports Fastboot mode, `ember-fetch` should also be listed as a [peer dependency](https://docs.npmjs.com/files/package.json#peerdependencies).
This is because Fastboot only invokes top-level addon's `updateFastBootManifest` ([detail](https://github.com/ember-fastboot/ember-cli-fastboot/issues/597)), thus `ember-fetch` has to be a top-level addon installed by the host app.

### Allow native fetch
`ember-fetch` allows access to native fetch in browser through a build config flag:
```js
Expand Down
1 change: 0 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ init:
environment:
MOCHA_REPORTER: "mocha-appveyor-reporter"
matrix:
- nodejs_version: "6"
- nodejs_version: "8"
- nodejs_version: "10"

Expand Down
138 changes: 68 additions & 70 deletions config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,81 @@

const getChannelURL = require('ember-source-channel-url');

module.exports = function() {
return Promise.all([
getChannelURL('release'),
getChannelURL('beta'),
getChannelURL('canary')
]).then((urls) => {
return {
useYarn: true,
scenarios: [
{
name: 'ember-lts-2.16',
env: {
EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true })
},
npm: {
devDependencies: {
'@ember/jquery': '^0.5.1',
'ember-source': '~2.16.0'
}
module.exports = async function() {
return {
useYarn: true,
scenarios: [
{
name: 'ember-lts-3.4',
npm: {
devDependencies: {
'ember-source': '~3.4.0'
}
},
{
name: 'ember-lts-2.18',
env: {
EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true })
},
npm: {
devDependencies: {
'@ember/jquery': '^0.5.1',
'ember-source': '~2.18.0'
}
}
},
{
name: 'ember-lts-3.8',
npm: {
devDependencies: {
'ember-source': '~3.8.0'
}
},
{
name: 'ember-release',
npm: {
devDependencies: {
'ember-source': urls[0]
}
}
},
{
name: 'ember-lts-3.12',
npm: {
devDependencies: {
'ember-source': '~3.12.0'
}
},
{
name: 'ember-beta',
npm: {
devDependencies: {
'ember-source': urls[1]
}
}
},
{
name: 'ember-release',
npm: {
devDependencies: {
'ember-source': await getChannelURL('release')
}
},
{
name: 'ember-canary',
npm: {
devDependencies: {
'ember-source': urls[2]
}
}
},
{
name: 'ember-beta',
npm: {
devDependencies: {
'ember-source': await getChannelURL('beta')
}
},
{
name: 'ember-default',
npm: {
devDependencies: {}
}
},
{
name: 'ember-canary',
npm: {
devDependencies: {
'ember-source': await getChannelURL('canary')
}
}
},
// The default `.travis.yml` runs this scenario via `npm test`,
// not via `ember try`. It's still included here so that running
// `ember try:each` manually or from a customized CI config will run it
// along with all the other scenarios.
{
name: 'ember-default',
npm: {
devDependencies: {}
}
},
{
name: 'ember-default-with-jquery',
env: {
EMBER_OPTIONAL_FEATURES: JSON.stringify({
'jquery-integration': true
})
},
{
name: 'ember-default-with-jquery',
env: {
EMBER_OPTIONAL_FEATURES: JSON.stringify({
'jquery-integration': true
})
},
npm: {
devDependencies: {
'@ember/jquery': '^0.5.1'
}
npm: {
devDependencies: {
'@ember/jquery': '^0.5.1'
}
}
]
};
});
}
]
};
};
53 changes: 8 additions & 45 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const concat = require('broccoli-concat');
const map = stew.map;
const Rollup = require('broccoli-rollup');
const BroccoliDebug = require('broccoli-debug');
const calculateCacheKeyForTree = require('calculate-cache-key-for-tree');
const SilentError = require('silent-error');

const debug = BroccoliDebug.buildDebugCallback('ember-fetch');

Expand Down Expand Up @@ -65,23 +65,20 @@ module.exports = {
* which allows us to use the `import()` method to tell it to include a file
* from our `vendor` tree into the final built app.
*/
included: function() {
included(app) {
this._super.included.apply(this, arguments);

let app = this._findApp();
let importTarget = app;

if (typeof this.import === 'function') {
importTarget = this;
if (this.parent.parent) {
throw new SilentError(`ember-fetch is found to be dependency of "${this.parent.name}", please only install ember-fetch as top-level addon to avoid conflict versions or duplicate assets.`);
}

app._fetchBuildConfig = Object.assign({
this._fetchBuildConfig = Object.assign({
preferNative: false,
alwaysIncludePolyfill: false,
browsers: this.project.targets && this.project.targets.browsers
}, app.options['ember-fetch']);

importTarget.import('vendor/ember-fetch.js', {
app.import('vendor/ember-fetch.js', {
exports: {
default: [
'default',
Expand All @@ -106,8 +103,7 @@ module.exports = {
treeForVendor() {
let babelAddon = this.addons.find(addon => addon.name === 'ember-cli-babel');

const app = this._findApp();
const options = app._fetchBuildConfig;
const options = this._fetchBuildConfig;

let browserTree = this.treeForBrowserFetch(options);
if (babelAddon) {
Expand All @@ -129,21 +125,6 @@ module.exports = {
}`), 'wrapped');
},

// Only include public/fetch-fastboot.js if top level addon
treeForPublic() {
return !this.parent.parent ? this._super.treeForPublic.apply(this, arguments) : null;
},

cacheKeyForTree(treeType) {
if (treeType === 'public') {
return calculateCacheKeyForTree('public', this, [!this.parent.parent]);
} else {
// make sure results of other treeFor* methods won't get opt-out of cache
// including the "treeForVendor"
return calculateCacheKeyForTree(treeType, this);
}
},

// Add node version of fetch.js into fastboot package.json manifest vendorFiles array
updateFastBootManifest(manifest) {
manifest.vendorFiles.push('ember-fetch/fetch-fastboot.js');
Expand Down Expand Up @@ -217,23 +198,5 @@ module.exports = {

let browserList = browsers.join(', ');
return caniuse.isSupported(featureName, browserList);
},

_findApp() {
if (typeof this._findHost === 'function') {
return this._findHost();
} else {
// Otherwise, we'll use this implementation borrowed from the _findHost()
// method in ember-cli.
// Keep iterating upward until we don't have a grandparent.
// Has to do this grandparent check because at some point we hit the project.
let app;
let current = this;
do {
app = current.app || this;
} while (current.parent && current.parent.parent && (current = current.parent));

return app;
}
},
}
};
Loading