diff --git a/.eslintrc.js b/.eslintrc.js index e1308a26..58f7d3a5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -57,6 +57,14 @@ module.exports = { }, plugins: ['node'], extends: ['plugin:node/recommended'], + rules: { + 'node/no-missing-require': [ + 'error', + { + allowModules: ['ember-web-app'], + }, + ], + }, }, // mocha files { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf46231f..91836322 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,7 @@ jobs: lint: name: Linting runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: actions/checkout@v1 @@ -23,6 +24,7 @@ jobs: test-ember: name: Tests / Ember runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v1 @@ -34,6 +36,7 @@ jobs: test-node: name: Tests / Node runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@v1 @@ -49,6 +52,7 @@ jobs: test-float: name: Tests / floating dependencies runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: actions/checkout@v1 @@ -61,6 +65,7 @@ jobs: name: Tests / ${{ matrix.ember-try-scenario }} runs-on: ubuntu-latest needs: [lint, test-ember] + timeout-minutes: 10 strategy: matrix: @@ -68,10 +73,12 @@ jobs: - ember-lts-3.16 - ember-lts-3.20 - ember-release - - ember-beta - - ember-canary + # - ember-beta + # - ember-canary - ember-default-with-jquery - ember-classic + - embroider-safe + # - embroider-optimized steps: - uses: actions/checkout@v1 diff --git a/blueprints/ember-web-app/index.js b/blueprints/ember-web-app/index.js index 20cf608d..3604fd70 100644 --- a/blueprints/ember-web-app/index.js +++ b/blueprints/ember-web-app/index.js @@ -3,6 +3,7 @@ const { EOL } = require('os'); const path = require('path'); const Manifest = require('../../lib/manifest'); const Browserconfig = require('../../lib/browserconfig'); +const pkg = require('../../index'); module.exports = { description: 'Generates a configuration for web app manifest.', @@ -29,11 +30,32 @@ module.exports = { }; }, - afterInstall() { + async afterInstall() { + await Promise.all([ + this._insertIntoAppIndexHTML(), + this._insertIntoEmberCLIBuildJS(), + ]); + }, + + async _insertIntoAppIndexHTML() { let index = path.join('app', 'index.html'); let content = `${EOL} ${Manifest.tag}${EOL} ${Browserconfig.tag}`; let after = `{{content-for "head"}}${EOL}`; - return this.insertIntoFile(index, content, { after }); + await this.insertIntoFile(index, content, { after }); + }, + + async _insertIntoEmberCLIBuildJS() { + await this.insertIntoFile( + 'ember-cli-build.js', + `const { treeForManifest } = require('${pkg.name}');`, + { + after: `const EmberApp = require('ember-cli/lib/broccoli/ember-app');${EOL}`, + } + ); + + await this.insertIntoFile('ember-cli-build.js', '[treeForManifest(app)]', { + after: 'app.toTree(', + }); }, }; diff --git a/config/ember-try.js b/config/ember-try.js index f14ac7f5..72f0ea60 100644 --- a/config/ember-try.js +++ b/config/ember-try.js @@ -1,6 +1,7 @@ 'use strict'; const getChannelURL = require('ember-source-channel-url'); +const { embroiderSafe, embroiderOptimized } = require('@embroider/test-setup'); module.exports = async function () { return { @@ -74,6 +75,8 @@ module.exports = async function () { }, }, }, + embroiderSafe(), + embroiderOptimized(), ], }; }; diff --git a/ember-cli-build.js b/ember-cli-build.js index ba0649dc..39a8ffca 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -1,6 +1,8 @@ 'use strict'; const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); +const { maybeEmbroider } = require('@embroider/test-setup'); +const { treeForManifest } = require('./index'); module.exports = function (defaults) { let app = new EmberAddon(defaults, { @@ -14,5 +16,7 @@ module.exports = function (defaults) { behave. You most likely want to be modifying `./index.js` or app's build file */ - return app.toTree(); + return maybeEmbroider(app, { + extraPublicTrees: [treeForManifest(app)], + }); }; diff --git a/index.js b/index.js index c38fab53..4a6945ec 100644 --- a/index.js +++ b/index.js @@ -3,9 +3,10 @@ const BroccoliMergeTrees = require('broccoli-merge-trees'); const Manifest = require('./lib/manifest'); const Browserconfig = require('./lib/browserconfig'); const tags = require('./lib/tags'); +const pkg = require('./package'); module.exports = { - name: require('./package').name, + name: pkg.name, shouldIncludeChildAddon(childAddon) { if (childAddon.name === 'broccoli-asset-rev') { @@ -15,8 +16,7 @@ module.exports = { return this._super.shouldIncludeChildAddon.apply(this, arguments); }, - included(app) { - this.app = app; + _treeForManifest(app) { app.options = app.options || {}; app.options[this.name] = app.options[this.name] || {}; @@ -26,19 +26,19 @@ module.exports = { this.manifest.configureFingerprint(); this.browserconfig.configureFingerprint(); - this._super.included.apply(this, arguments); - }, - - treeForPublic() { - let manifest = this.manifest.toTree(); - let browserconfig = this.browserconfig.toTree(); - - return new BroccoliMergeTrees([manifest, browserconfig]); + return new BroccoliMergeTrees([ + this.manifest.toTree(), + this.browserconfig.toTree(), + ]); }, contentFor(section) { - if (section === 'head') { + if (this.manifest && section === 'head') { return tags(this.manifest.configuration); } }, }; + +module.exports.treeForManifest = function treeForManifest(app) { + return app.project.findAddonByName(pkg.name)._treeForManifest(app); +}; diff --git a/node-tests/acceptance/fixtures/broccoli-asset-rev/ember-cli-build.js b/node-tests/acceptance/fixtures/broccoli-asset-rev/ember-cli-build.js index 50b88fd0..95b889aa 100644 --- a/node-tests/acceptance/fixtures/broccoli-asset-rev/ember-cli-build.js +++ b/node-tests/acceptance/fixtures/broccoli-asset-rev/ember-cli-build.js @@ -1,4 +1,5 @@ const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { treeForManifest } = require('ember-web-app'); module.exports = function (defaults) { let options = { @@ -10,5 +11,5 @@ module.exports = function (defaults) { let app = new EmberApp(defaults, options); - return app.toTree(); + return app.toTree([treeForManifest(app)]); }; diff --git a/node-tests/acceptance/fixtures/config-root-url/ember-cli-build.js b/node-tests/acceptance/fixtures/config-root-url/ember-cli-build.js new file mode 100644 index 00000000..c0fceb53 --- /dev/null +++ b/node-tests/acceptance/fixtures/config-root-url/ember-cli-build.js @@ -0,0 +1,8 @@ +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { treeForManifest } = require('ember-web-app'); + +module.exports = function (defaults) { + let app = new EmberApp(defaults); + + return app.toTree([treeForManifest(app)]); +}; diff --git a/node-tests/acceptance/fixtures/dummy/ember-cli-build.js b/node-tests/acceptance/fixtures/dummy/ember-cli-build.js new file mode 100644 index 00000000..c0fceb53 --- /dev/null +++ b/node-tests/acceptance/fixtures/dummy/ember-cli-build.js @@ -0,0 +1,8 @@ +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { treeForManifest } = require('ember-web-app'); + +module.exports = function (defaults) { + let app = new EmberApp(defaults); + + return app.toTree([treeForManifest(app)]); +}; diff --git a/node-tests/acceptance/fixtures/no-browserconfig/ember-cli-build.js b/node-tests/acceptance/fixtures/no-browserconfig/ember-cli-build.js new file mode 100644 index 00000000..c0fceb53 --- /dev/null +++ b/node-tests/acceptance/fixtures/no-browserconfig/ember-cli-build.js @@ -0,0 +1,8 @@ +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { treeForManifest } = require('ember-web-app'); + +module.exports = function (defaults) { + let app = new EmberApp(defaults); + + return app.toTree([treeForManifest(app)]); +}; diff --git a/node-tests/acceptance/fixtures/root-url-fingerprint/ember-cli-build.js b/node-tests/acceptance/fixtures/root-url-fingerprint/ember-cli-build.js index cb89c902..27ae24c6 100644 --- a/node-tests/acceptance/fixtures/root-url-fingerprint/ember-cli-build.js +++ b/node-tests/acceptance/fixtures/root-url-fingerprint/ember-cli-build.js @@ -1,4 +1,5 @@ const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { treeForManifest } = require('ember-web-app'); module.exports = function (defaults) { let options = { @@ -9,5 +10,5 @@ module.exports = function (defaults) { let app = new EmberApp(defaults, options); - return app.toTree(); + return app.toTree([treeForManifest(app)]); }; diff --git a/node-tests/blueprints/ember-web-app-test.js b/node-tests/blueprints/ember-web-app-test.js index 4caa7d88..894c4e9c 100644 --- a/node-tests/blueprints/ember-web-app-test.js +++ b/node-tests/blueprints/ember-web-app-test.js @@ -1,10 +1,11 @@ 'use strict'; +const { EOL } = require('os'); const { expect } = require('ember-cli-blueprint-test-helpers/chai'); + const { setupTestHooks, emberNew, emberGenerate, - emberGenerateDestroy, emberDestroy, } = require('ember-cli-blueprint-test-helpers/helpers'); @@ -12,31 +13,27 @@ describe('Blueprints', function () { setupTestHooks(this); describe('ember generate', function () { - it('generates config/manifest.js file', function () { + it('generates files', function () { let args = ['ember-web-app', 'foo']; return emberNew().then(() => - emberGenerateDestroy(args, (file) => { + emberGenerate(args, (file) => { expect(file('config/manifest.js')) .to.contain('name: "my-app"') .to.contain('short_name: "my-app"') .to.contain('display: "standalone"'); - }) - ); - }); - it('adds manifest link & browserconfig meta into app/index.html file', function () { - let args = ['ember-web-app', 'foo']; - - return emberNew().then(() => - emberGenerate(args, (file) => { expect(file('app/index.html')) .to.contain( - '' + '' ) .to.contain( '' ); + + expect(file('ember-cli-build.js')) + .to.contain(`const { treeForManifest } = require('ember-web-app');`) + .to.contain(`return app.toTree([treeForManifest(app)]${EOL});`); }).then(() => emberDestroy(args)) ); }); diff --git a/package.json b/package.json index e5204220..a4ca91ac 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "release": "release-it", "changelog": "lerna-changelog", "fast-test": "SKIP_ACCEPTANCE=true yarn node-test", - "node-test": "nyc --reporter=lcov mocha --recursive node-tests", + "node-test": "nyc --reporter=lcov mocha --recursive node-tests/**/*-test.js", "lint": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*", "lint:hbs": "ember-template-lint .", "lint:js": "eslint . --cache", @@ -47,6 +47,7 @@ "devDependencies": { "@ember/optional-features": "^2.0.0", "@ember/test-helpers": "^2.4.2", + "@embroider/test-setup": "^0.43.5", "@glimmer/component": "^1.0.4", "@glimmer/tracking": "^1.0.4", "babel-eslint": "^10.1.0", @@ -117,4 +118,4 @@ "node": "12.22.1", "yarn": "1.22.10" } -} \ No newline at end of file +} diff --git a/tests/dummy/app/templates/docs/advanced/fingerprinting.md b/tests/dummy/app/templates/docs/advanced/fingerprinting.md index 5a74f3bd..1a80944f 100644 --- a/tests/dummy/app/templates/docs/advanced/fingerprinting.md +++ b/tests/dummy/app/templates/docs/advanced/fingerprinting.md @@ -7,19 +7,20 @@ The following example prepends with a custom domain and adds fingerprint checksu ```javascript 'use strict'; const EmberApp = require('ember-cli/lib/broccoli/ember-app'); -const broccoliAssetRevDefaults = require('broccoli-asset-rev/lib/default-options'); +const { treeForManifest } = require('ember-web-app'); +const { extensions } = require('broccoli-asset-rev/lib/default-options'); -module.exports = function(defaults) { +module.exports = function (defaults) { let options = { fingerprint: { - extensions: broccoliAssetRevDefaults.extensions.concat(['webmanifest']), + extensions: [...extensions, 'webmanifest'], prepend: 'https://www.example.com/', }, }; let app = new EmberApp(defaults, options); - return app.toTree(); + return app.toTree([treeForManifest(app)]); }; ``` diff --git a/tests/dummy/app/templates/docs/advanced/generating-icons.md b/tests/dummy/app/templates/docs/advanced/generating-icons.md index 4237ff4a..a37655ec 100644 --- a/tests/dummy/app/templates/docs/advanced/generating-icons.md +++ b/tests/dummy/app/templates/docs/advanced/generating-icons.md @@ -7,7 +7,7 @@ If your `config/manifest.js` looks like this and needs a `192px` and a `512px` i ```javascript 'use strict'; -module.exports = function() { +module.exports = function () { return { icons: [ { @@ -15,7 +15,7 @@ module.exports = function() { sizes: '32x32', targets: ['favicon'], }, - ...[192, 280, 512].map(size => ({ + ...[192, 280, 512].map((size) => ({ src: `/assets/icons/appicon-${size}.png`, sizes: `${size}x${size}`, })), @@ -28,8 +28,10 @@ You can start with a base `brand-icon.svg` image and automatically build the `19 ```javascript 'use strict'; +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { treeForManifest } = require('ember-web-app'); -module.exports = function(defaults) { +module.exports = function (defaults) { let options = { 'ember-cli-image-transformer': { images: [ @@ -46,6 +48,6 @@ module.exports = function(defaults) { let app = new EmberApp(defaults, options); - return app.toTree(); + return app.toTree([treeForManifest(app)]); }; ``` diff --git a/tests/dummy/app/templates/docs/getting-started/installation.md b/tests/dummy/app/templates/docs/getting-started/installation.md index c252bf78..fc29d001 100644 --- a/tests/dummy/app/templates/docs/getting-started/installation.md +++ b/tests/dummy/app/templates/docs/getting-started/installation.md @@ -6,13 +6,49 @@ To install Web App, run ember install ember-web-app ``` -Ember should install the addon, add a `config/manifest.js` file, and insert HTML tags for `manifest.webmanifest` and `browserconfig.xml` into `app/index.html` file. +Ember should install the addon, add a `config/manifest.js` file, insert HTML tags for `manifest.webmanifest` and `browserconfig.xml` into `app/index.html` file, and update `ember-cli-build.js` file. ```html + - - + + ``` +```javascript +// ember-cli-build.js +'use strict'; + +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { treeForManifest } = require('ember-web-app'); + +module.exports = function (defaults) { + let app = new EmberApp(defaults, {}); + + return app.toTree([treeForManifest(app)]); +}; +``` + Check out the {{docs-link "upgrade guide" "docs.getting-started.upgrade-guide"}} if you're coming from a previous version of Web App. + +## Embroider + +When application uses Embroider, then pass manifest tree into `extraPublicTrees` configuration property. + +```javascript +// ember-cli-build.js +'use strict'; + +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); +const { treeForManifest } = require('ember-web-app'); + +module.exports = function (defaults) { + let app = new EmberApp(defaults, {}); + + const { Webpack } = require('@embroider/webpack'); + return require('@embroider/compat').compatBuild(app, Webpack, { + extraPublicTrees: [treeForManifest(app)], + }); +}; +``` diff --git a/tests/dummy/app/templates/docs/getting-started/overview.md b/tests/dummy/app/templates/docs/getting-started/overview.md index 846bdc35..af49036c 100644 --- a/tests/dummy/app/templates/docs/getting-started/overview.md +++ b/tests/dummy/app/templates/docs/getting-started/overview.md @@ -14,7 +14,7 @@ From [MDN](https://developer.mozilla.org/en-US/docs/Web/Manifest) The generated `manifest.webmanifest` file is linked to the application using `link` tag in `app/index.html` file. ```html - + ``` _The generated manifest is validated using `web-app-manifest-validator` package._ @@ -28,7 +28,7 @@ From [Microsoft](https://msdn.microsoft.com/en-us/library/dn320426%28v=vs.85%29. The generated `browserconfig.xml` file is linked to the application using `meta` tag in `app/index.html` file. ```html - + ``` _You can skip generating of `browserconfig.xml` file by removing the `meta` tag from the `app/index.html` file._ diff --git a/tests/dummy/app/templates/docs/getting-started/upgrade-guide.md b/tests/dummy/app/templates/docs/getting-started/upgrade-guide.md index 2b504ca2..f7ae7df7 100644 --- a/tests/dummy/app/templates/docs/getting-started/upgrade-guide.md +++ b/tests/dummy/app/templates/docs/getting-started/upgrade-guide.md @@ -16,12 +16,51 @@ You can view all of Web App's release notes on [our Releases page](https://githu ## 6.0 Upgrade Guide -There was one breaking change made in the 6.0 release. +There were two breaking changes made in the 6.0 release. ### 1. Drop Node.js 10 support Web App supports Node.js 12, 14, and 16+ versions. +### 2. Use `treeForManifest` for Embroider compatibility + +Since Embroider removes support for `treeForPublic`, this add-on needs a different way to hook into the build pipeline. + +#### Classic `ember-cli-build.js` + +```diff +'use strict'; + +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); ++const { treeForManifest } = require('ember-web-app'); + +module.exports = function (defaults) { + let app = new EmberApp(defaults, {}); + +- return app.toTree(); ++ return app.toTree([treeForManifest(app)]); +}; +``` + +#### Embroider `ember-cli-build.js` + +```diff +'use strict'; + +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); ++const { treeForManifest } = require('ember-web-app'); + +module.exports = function (defaults) { + let app = new EmberApp(defaults, {}); + + const { Webpack } = require('@embroider/webpack'); +- return require('@embroider/compat').compatBuild(app, Webpack); ++ return require('@embroider/compat').compatBuild(app, Webpack, { ++ extraPublicTrees: [treeForManifest(app)], ++ }); +}; +``` + ## 5.0 Upgrade Guide There were a two breaking changes made in the 5.0 release. diff --git a/yarn.lock b/yarn.lock index 46231c79..9c9ee497 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1361,6 +1361,14 @@ semver "^7.3.2" typescript-memoize "^1.0.0-alpha.3" +"@embroider/test-setup@^0.43.5": + version "0.43.5" + resolved "https://registry.yarnpkg.com/@embroider/test-setup/-/test-setup-0.43.5.tgz#79944cb50038802cc71d50aa0d5d7a0955ee6349" + integrity sha512-ke+5B0VR2343ZrOqV9Ok2LyA4m2q2ApM1Oy1RC8+3+OI5lDVg8UgZG9n/G2e77KPMFxnK3eVpXcPdLcdOxW6+w== + dependencies: + lodash "^4.17.21" + resolve "^1.20.0" + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"