From 77e739a59964a3c280f2965948d7d2e2ff5b8452 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Tue, 1 Feb 2022 15:38:19 -0500 Subject: [PATCH 1/8] Add typecsript sample rollup config --- .../sample-typescript-rollup.config.js | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 packages/addon-dev/sample-typescript-rollup.config.js diff --git a/packages/addon-dev/sample-typescript-rollup.config.js b/packages/addon-dev/sample-typescript-rollup.config.js new file mode 100644 index 000000000..12779d1e1 --- /dev/null +++ b/packages/addon-dev/sample-typescript-rollup.config.js @@ -0,0 +1,113 @@ +/** + * This file should live at ./config/rollup.config.js + * and the babel config at ./config/babel.config.js (if the babel config is ESM) + * _if the babel config is CJS, it can be at the addon root_ + * + * The command to build: + * + * `rollup -c ./config/rollup.config.js` + */ +import path from 'path'; + +import alias from '@rollup/plugin-alias'; +import multiInput from 'rollup-plugin-multi-input'; +import ts from 'rollup-plugin-ts'; +import { defineConfig } from 'rollup'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import { Addon } from '@embroider/addon-dev/rollup'; + +import babelConfig from './babel.config'; +import packageJson from '../package.json'; + +const addon = new Addon({ + srcDir: 'src', + destDir: 'dist', +}); + +const transpilation = [ + // Instruct rollup how to resolve ts and hbs imports + // (importing a template-only component, for example) + nodeResolve({ resolveOnly: ['./'], extensions: ['.js', '.ts', '.hbs'] }), + + // Allow top-level imports (what folks are used to from v1 addons) + // During the build, anything referencing a top-level import will be + // replaced with a relative import. + // DANGER: it's somewhat easy to cause circular references with this tool + alias({ + entries: [ + { + find: '#types', + replacement: path.resolve('src', '-private', 'types.ts'), + }, + { + find: packageJson.name, + replacement: path.resolve('src'), + }, + { + find: `${packageJson.name}/(.*)`, + replacement: path.resolve('src/$1'), + }, + ], + }), + + // This babel config should *not* apply presets or compile away ES modules. + // It exists only to provide development niceties for you, like automatic + // template colocation. + // See `babel.config.json` for the actual Babel configuration! + ts({ + // can be changed to swc or other transpilers later + // but we need the ember plugins converted first + // (template compilation and co-location) + transpiler: 'babel', + browserslist: false, + babelConfig, + // setting this true greatly improves performance, but + // at the cost of safety (and no declarations output in your dist directory). + transpileOnly: false, + tsconfig: { + fileName: 'tsconfig.json', + hook: (config) => ({ ...config, declaration: true }), + }, + }), + + // Follow the V2 Addon rules about dependencies. Your code can import from + // `dependencies` and `peerDependencies` as well as standard Ember-provided + // package names. + addon.dependencies(), + + // Ensure that standalone .hbs files are properly integrated as Javascript. + addon.hbs(), + + // addons are allowed to contain imports of .css files, which we want rollup + // to leave alone and keep in the published output. + // addon.keepAssets(['**/*.css']), +]; + +// these should be JS, even though the authored format is TS +const globallyAvailable = ['components/**/*.js', 'services/*.js']; + +export default defineConfig({ + input: ['src/**/*{js,hbs,ts}'], + output: addon.output(), + plugins: [ + // allows specifying glob inputs so we can transpile each module separately + multiInput(), + + ...transpilation, + + // These are the modules that users should be able to import from your + // addon. Anything not listed here may get optimized away. + addon.publicEntrypoints([...globallyAvailable]), + + // These are the modules that should get reexported into the traditional + // "app" tree. Things in here should also be in publicEntrypoints above, but + // not everything in publicEntrypoints necessarily needs to go here. + // + // This generates an `_app_/` directory in your output directory + // and updates an 'ember-addon.app-js' entry in your package.json + addon.appReexports([...globallyAvailable]), + + // Remove leftover build artifacts when starting a new build. + addon.clean(), + ], +}); From b9ac0480249ca3c61a33e712b8d5c9a907a8894f Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Thu, 3 Feb 2022 18:42:26 -0500 Subject: [PATCH 2/8] Updates, based on: https://github.com/embroider-build/embroider/pull/1106 --- .../sample-typescript-rollup.config.js | 132 ++++++++---------- 1 file changed, 61 insertions(+), 71 deletions(-) diff --git a/packages/addon-dev/sample-typescript-rollup.config.js b/packages/addon-dev/sample-typescript-rollup.config.js index 12779d1e1..c1c12d0fe 100644 --- a/packages/addon-dev/sample-typescript-rollup.config.js +++ b/packages/addon-dev/sample-typescript-rollup.config.js @@ -10,94 +10,28 @@ import path from 'path'; import alias from '@rollup/plugin-alias'; -import multiInput from 'rollup-plugin-multi-input'; import ts from 'rollup-plugin-ts'; import { defineConfig } from 'rollup'; -import { nodeResolve } from '@rollup/plugin-node-resolve'; import { Addon } from '@embroider/addon-dev/rollup'; -import babelConfig from './babel.config'; -import packageJson from '../package.json'; +import packageJson from './package.json'; const addon = new Addon({ srcDir: 'src', destDir: 'dist', }); -const transpilation = [ - // Instruct rollup how to resolve ts and hbs imports - // (importing a template-only component, for example) - nodeResolve({ resolveOnly: ['./'], extensions: ['.js', '.ts', '.hbs'] }), - - // Allow top-level imports (what folks are used to from v1 addons) - // During the build, anything referencing a top-level import will be - // replaced with a relative import. - // DANGER: it's somewhat easy to cause circular references with this tool - alias({ - entries: [ - { - find: '#types', - replacement: path.resolve('src', '-private', 'types.ts'), - }, - { - find: packageJson.name, - replacement: path.resolve('src'), - }, - { - find: `${packageJson.name}/(.*)`, - replacement: path.resolve('src/$1'), - }, - ], - }), - - // This babel config should *not* apply presets or compile away ES modules. - // It exists only to provide development niceties for you, like automatic - // template colocation. - // See `babel.config.json` for the actual Babel configuration! - ts({ - // can be changed to swc or other transpilers later - // but we need the ember plugins converted first - // (template compilation and co-location) - transpiler: 'babel', - browserslist: false, - babelConfig, - // setting this true greatly improves performance, but - // at the cost of safety (and no declarations output in your dist directory). - transpileOnly: false, - tsconfig: { - fileName: 'tsconfig.json', - hook: (config) => ({ ...config, declaration: true }), - }, - }), - - // Follow the V2 Addon rules about dependencies. Your code can import from - // `dependencies` and `peerDependencies` as well as standard Ember-provided - // package names. - addon.dependencies(), - - // Ensure that standalone .hbs files are properly integrated as Javascript. - addon.hbs(), - - // addons are allowed to contain imports of .css files, which we want rollup - // to leave alone and keep in the published output. - // addon.keepAssets(['**/*.css']), +const globallyAvailable = [ + 'components/**/*.{js,ts}', 'services/**/*.{js,ts}', 'helpers/**/*.{js,ts}', + 'instance-initializers/**/*.{js,ts}' ]; -// these should be JS, even though the authored format is TS -const globallyAvailable = ['components/**/*.js', 'services/*.js']; - export default defineConfig({ - input: ['src/**/*{js,hbs,ts}'], output: addon.output(), plugins: [ - // allows specifying glob inputs so we can transpile each module separately - multiInput(), - - ...transpilation, - // These are the modules that users should be able to import from your // addon. Anything not listed here may get optimized away. - addon.publicEntrypoints([...globallyAvailable]), + addon.publicEntrypoints(['*.{js,ts}', ...globallyAvailable]), // These are the modules that should get reexported into the traditional // "app" tree. Things in here should also be in publicEntrypoints above, but @@ -107,6 +41,62 @@ export default defineConfig({ // and updates an 'ember-addon.app-js' entry in your package.json addon.appReexports([...globallyAvailable]), + // Allow top-level imports (what folks are used to from v1 addons) + // During the build, anything referencing a top-level import will be + // replaced with a relative import. + // DANGER: it's somewhat easy to cause circular references with this tool + alias({ + entries: [ + { + find: '#types', + replacement: path.resolve('src', '-private', 'types.ts'), + }, + { + find: packageJson.name, + replacement: path.resolve('src'), + }, + { + find: `${packageJson.name}/(.*)`, + replacement: path.resolve('src/$1'), + }, + ], + }), + + // This babel config should *not* apply presets or compile away ES modules. + // It exists only to provide development niceties for you, like automatic + // template colocation. + // See `babel.config.json` for the actual Babel configuration! + ts({ + // can be changed to swc or other transpilers later + // but we need the ember plugins converted first + // (template compilation and co-location) + transpiler: 'babel', + browserslist: false, + // NOTE: babel config must be CJS if in the same directory as CWD + // https://github.com/wessberg/rollup-plugin-ts/issues/167 + // otherwise ESM babel.config.js can be imported and set here + // babelConfig, + // setting this true greatly improves performance, but + // at the cost of safety (and no declarations output in your dist directory). + transpileOnly: false, + tsconfig: { + fileName: 'tsconfig.json', + hook: (config) => ({ ...config, declaration: true }), + }, + }), + + // Follow the V2 Addon rules about dependencies. Your code can import from + // `dependencies` and `peerDependencies` as well as standard Ember-provided + // package names. + addon.dependencies(), + + // Ensure that standalone .hbs files are properly integrated as Javascript. + addon.hbs(), + + // addons are allowed to contain imports of .css files, which we want rollup + // to leave alone and keep in the published output. + addon.keepAssets(['**/*.css']), + // Remove leftover build artifacts when starting a new build. addon.clean(), ], From aeea1444f1248108e2e2f3b0b46c5f478b313dba Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Thu, 3 Feb 2022 18:42:56 -0500 Subject: [PATCH 3/8] Update sample-typescript-rollup.config.js --- packages/addon-dev/sample-typescript-rollup.config.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/addon-dev/sample-typescript-rollup.config.js b/packages/addon-dev/sample-typescript-rollup.config.js index c1c12d0fe..acd93dcf7 100644 --- a/packages/addon-dev/sample-typescript-rollup.config.js +++ b/packages/addon-dev/sample-typescript-rollup.config.js @@ -1,12 +1,3 @@ -/** - * This file should live at ./config/rollup.config.js - * and the babel config at ./config/babel.config.js (if the babel config is ESM) - * _if the babel config is CJS, it can be at the addon root_ - * - * The command to build: - * - * `rollup -c ./config/rollup.config.js` - */ import path from 'path'; import alias from '@rollup/plugin-alias'; From 791a27eec9bb75aae7786ddcb43654d91d73ae1b Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Sat, 5 Feb 2022 15:00:29 -0500 Subject: [PATCH 4/8] Remove alias plugin, as tooling will eventually support aliases / "self imports" via package.json exports https://nodejs.org/api/packages.html#packages_self_referencing_a_package_using_its_name --- .../sample-typescript-rollup.config.js | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/packages/addon-dev/sample-typescript-rollup.config.js b/packages/addon-dev/sample-typescript-rollup.config.js index acd93dcf7..794feb438 100644 --- a/packages/addon-dev/sample-typescript-rollup.config.js +++ b/packages/addon-dev/sample-typescript-rollup.config.js @@ -1,12 +1,9 @@ import path from 'path'; -import alias from '@rollup/plugin-alias'; import ts from 'rollup-plugin-ts'; import { defineConfig } from 'rollup'; import { Addon } from '@embroider/addon-dev/rollup'; -import packageJson from './package.json'; - const addon = new Addon({ srcDir: 'src', destDir: 'dist', @@ -32,27 +29,6 @@ export default defineConfig({ // and updates an 'ember-addon.app-js' entry in your package.json addon.appReexports([...globallyAvailable]), - // Allow top-level imports (what folks are used to from v1 addons) - // During the build, anything referencing a top-level import will be - // replaced with a relative import. - // DANGER: it's somewhat easy to cause circular references with this tool - alias({ - entries: [ - { - find: '#types', - replacement: path.resolve('src', '-private', 'types.ts'), - }, - { - find: packageJson.name, - replacement: path.resolve('src'), - }, - { - find: `${packageJson.name}/(.*)`, - replacement: path.resolve('src/$1'), - }, - ], - }), - // This babel config should *not* apply presets or compile away ES modules. // It exists only to provide development niceties for you, like automatic // template colocation. From 40bd95fdb2a2ded1b2b2293fd7150b6460a2a724 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Sat, 4 Jun 2022 11:26:28 -0400 Subject: [PATCH 5/8] Update typescript sample rollup config and add babel typescript config --- .../sample-typescript-babel.config.cjs | 26 ++++++++ ...js => sample-typescript-rollup.config.mjs} | 65 ++++++++++++------- 2 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 packages/addon-dev/sample-typescript-babel.config.cjs rename packages/addon-dev/{sample-typescript-rollup.config.js => sample-typescript-rollup.config.mjs} (57%) diff --git a/packages/addon-dev/sample-typescript-babel.config.cjs b/packages/addon-dev/sample-typescript-babel.config.cjs new file mode 100644 index 000000000..34917b6f0 --- /dev/null +++ b/packages/addon-dev/sample-typescript-babel.config.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const { resolve } = require; + +module.exports = { + presets: [resolve('@babel/preset-typescript')], + plugins: [ + [ + resolve('@babel/plugin-transform-typescript'), + { + allowDeclareFields: true, + onlyRemoveTypeImports: true, + // Default enums are IIFEs + optimizeConstEnums: true, + }, + ], + [ + resolve('@babel/plugin-proposal-decorators'), + { + // The stage 1 implementation + legacy: true, + }, + ], + resolve('@embroider/addon-dev/template-colocation-plugin'), + ], +}; diff --git a/packages/addon-dev/sample-typescript-rollup.config.js b/packages/addon-dev/sample-typescript-rollup.config.mjs similarity index 57% rename from packages/addon-dev/sample-typescript-rollup.config.js rename to packages/addon-dev/sample-typescript-rollup.config.mjs index 794feb438..5b51e0fce 100644 --- a/packages/addon-dev/sample-typescript-rollup.config.js +++ b/packages/addon-dev/sample-typescript-rollup.config.mjs @@ -1,7 +1,6 @@ -import path from 'path'; - import ts from 'rollup-plugin-ts'; import { defineConfig } from 'rollup'; + import { Addon } from '@embroider/addon-dev/rollup'; const addon = new Addon({ @@ -9,26 +8,44 @@ const addon = new Addon({ destDir: 'dist', }); -const globallyAvailable = [ - 'components/**/*.{js,ts}', 'services/**/*.{js,ts}', 'helpers/**/*.{js,ts}', - 'instance-initializers/**/*.{js,ts}' -]; - export default defineConfig({ - output: addon.output(), + // https://github.com/rollup/rollup/issues/1828 + watch: { + chokidar: { + usePolling: true, + }, + }, + output: { + ...addon.output(), + sourcemap: true, + // Until a bug with the ember-cli-htmlbars-removal transform is fixed, you + // may need + // hoistTransitiveImports: false + // specified here as well + }, plugins: [ // These are the modules that users should be able to import from your // addon. Anything not listed here may get optimized away. - addon.publicEntrypoints(['*.{js,ts}', ...globallyAvailable]), + addon.publicEntrypoints([ + 'index.ts', + 'components/**/*.ts', + 'helpers/**/*.ts', + 'modifiers/**/*.ts', + 'services/**/*.ts', + 'test-support/**/*.ts', + ]), // These are the modules that should get reexported into the traditional // "app" tree. Things in here should also be in publicEntrypoints above, but // not everything in publicEntrypoints necessarily needs to go here. - // - // This generates an `_app_/` directory in your output directory - // and updates an 'ember-addon.app-js' entry in your package.json - addon.appReexports([...globallyAvailable]), - + addon.appReexports([ + 'index.{js,ts}', + 'components/**/*.{js,ts}', + 'helpers/**/*.{js,ts}', + 'modifiers/**/*.{js,ts}', + 'services/**/*.{js,ts}', + 'test-support/**/*.{js,ts}', + ]), // This babel config should *not* apply presets or compile away ES modules. // It exists only to provide development niceties for you, like automatic // template colocation. @@ -38,17 +55,18 @@ export default defineConfig({ // but we need the ember plugins converted first // (template compilation and co-location) transpiler: 'babel', - browserslist: false, - // NOTE: babel config must be CJS if in the same directory as CWD - // https://github.com/wessberg/rollup-plugin-ts/issues/167 - // otherwise ESM babel.config.js can be imported and set here - // babelConfig, - // setting this true greatly improves performance, but - // at the cost of safety (and no declarations output in your dist directory). - transpileOnly: false, + browserslist: ['last 2 firefox versions', 'last 2 chrome versions'], tsconfig: { fileName: 'tsconfig.json', - hook: (config) => ({ ...config, declaration: true }), + hook: (config) => ({ + ...config, + declaration: true, + declarationMap: true, + // See: https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#beta-delta + // Allows us to use `exports` to define types per export + // However, we can't use that feature until the minimum supported TS is 4.7+ + declarationDir: './dist', + }), }, }), @@ -64,7 +82,6 @@ export default defineConfig({ // to leave alone and keep in the published output. addon.keepAssets(['**/*.css']), - // Remove leftover build artifacts when starting a new build. addon.clean(), ], }); From 0b1408dac9a1ece7772debab5d8752716c4875a2 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Thu, 9 Jun 2022 14:56:11 -0400 Subject: [PATCH 6/8] Make all extensions js, and re-add the class properties transform, due to https://github.com/babel/ember-cli-babel/issues/447 --- .../sample-typescript-babel.config.cjs | 1 + .../sample-typescript-rollup.config.mjs | 24 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/addon-dev/sample-typescript-babel.config.cjs b/packages/addon-dev/sample-typescript-babel.config.cjs index 34917b6f0..2e0dbc367 100644 --- a/packages/addon-dev/sample-typescript-babel.config.cjs +++ b/packages/addon-dev/sample-typescript-babel.config.cjs @@ -21,6 +21,7 @@ module.exports = { legacy: true, }, ], + [resolve('@babel/plugin-proposal-class-properties')], resolve('@embroider/addon-dev/template-colocation-plugin'), ], }; diff --git a/packages/addon-dev/sample-typescript-rollup.config.mjs b/packages/addon-dev/sample-typescript-rollup.config.mjs index 5b51e0fce..c0f39b0ee 100644 --- a/packages/addon-dev/sample-typescript-rollup.config.mjs +++ b/packages/addon-dev/sample-typescript-rollup.config.mjs @@ -27,24 +27,24 @@ export default defineConfig({ // These are the modules that users should be able to import from your // addon. Anything not listed here may get optimized away. addon.publicEntrypoints([ - 'index.ts', - 'components/**/*.ts', - 'helpers/**/*.ts', - 'modifiers/**/*.ts', - 'services/**/*.ts', - 'test-support/**/*.ts', + 'index.js', + 'components/**/*.js', + 'helpers/**/*.js', + 'modifiers/**/*.js', + 'services/**/*.js', + 'test-support/**/*.js', ]), // These are the modules that should get reexported into the traditional // "app" tree. Things in here should also be in publicEntrypoints above, but // not everything in publicEntrypoints necessarily needs to go here. addon.appReexports([ - 'index.{js,ts}', - 'components/**/*.{js,ts}', - 'helpers/**/*.{js,ts}', - 'modifiers/**/*.{js,ts}', - 'services/**/*.{js,ts}', - 'test-support/**/*.{js,ts}', + 'index.js', + 'components/**/*.js', + 'helpers/**/*.js', + 'modifiers/**/*.js', + 'services/**/*.js', + 'test-support/**/*.js', ]), // This babel config should *not* apply presets or compile away ES modules. // It exists only to provide development niceties for you, like automatic From 984ad9c3cd9795be155fbab4e20f0c58f15d3194 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Thu, 9 Jun 2022 15:35:46 -0400 Subject: [PATCH 7/8] After testing at https://github.com/NullVoxPopuli/ember-popperjs/pull/168, the ts extenion in publicEntrypoints is needed --- .../addon-dev/sample-typescript-rollup.config.mjs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/addon-dev/sample-typescript-rollup.config.mjs b/packages/addon-dev/sample-typescript-rollup.config.mjs index c0f39b0ee..b4bdab3bb 100644 --- a/packages/addon-dev/sample-typescript-rollup.config.mjs +++ b/packages/addon-dev/sample-typescript-rollup.config.mjs @@ -27,12 +27,12 @@ export default defineConfig({ // These are the modules that users should be able to import from your // addon. Anything not listed here may get optimized away. addon.publicEntrypoints([ - 'index.js', - 'components/**/*.js', - 'helpers/**/*.js', - 'modifiers/**/*.js', - 'services/**/*.js', - 'test-support/**/*.js', + 'index.ts', + 'components/**/*.ts', + 'helpers/**/*.ts', + 'modifiers/**/*.ts', + 'services/**/*.ts', + 'test-support/**/*.ts', ]), // These are the modules that should get reexported into the traditional From 672470bf769020aecb6cf6bf1ad9777a30e02537 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Wed, 29 Jun 2022 16:13:57 -0400 Subject: [PATCH 8/8] Add notes about why certain config options are passed to rollup-plugin-ts --- packages/addon-dev/sample-typescript-rollup.config.mjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/addon-dev/sample-typescript-rollup.config.mjs b/packages/addon-dev/sample-typescript-rollup.config.mjs index b4bdab3bb..886e87211 100644 --- a/packages/addon-dev/sample-typescript-rollup.config.mjs +++ b/packages/addon-dev/sample-typescript-rollup.config.mjs @@ -55,8 +55,12 @@ export default defineConfig({ // but we need the ember plugins converted first // (template compilation and co-location) transpiler: 'babel', + // without the browserlist, recently landed JS features are polyfilled. + // It should be primarily up to the consuming app whether or not they need to + // polyfill whatever JS features. browserslist: ['last 2 firefox versions', 'last 2 chrome versions'], tsconfig: { + // when `hooks` is specified, fileName is required fileName: 'tsconfig.json', hook: (config) => ({ ...config,