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

For @embroider/addon-dev, should we also have swc plugins for for the colocation and template compilation stuff? #1097

Closed
NullVoxPopuli opened this issue Feb 1, 2022 · 1 comment

Comments

@NullVoxPopuli
Copy link
Collaborator

NullVoxPopuli commented Feb 1, 2022

Semi-related to this: #1095
Switching from the rollup-babel plugin to rollup-plugin-ts increase build time by about 5-6x (this is small addon, so idk if that scales).

More investigation needed, ofc -- just putting the idea out there.

These two rollup.config.js files are equivalent, _except for the usage of babel or ts (from rollup-plugin-ts):

with rollup-plugin-ts

image

// @ts-nocheck
import path from 'path';

import alias from '@rollup/plugin-alias';
import ts from 'rollup-plugin-ts';
import { babel } from '@rollup/plugin-babel';
import { defineConfig } from 'rollup';
import { nodeResolve } from '@rollup/plugin-node-resolve';

import { Addon } from '@embroider/addon-dev/rollup';

import babelConfig from './babel.config';

const addon = new Addon({
  srcDir: 'src',
  destDir: 'dist',
});

const extensions = ['.js', '.ts'];

const transpilation = [
  // Instruct rollup how to follow import paths for typescript files
  // (in JS-only libraries, this isn't needed)
  nodeResolve({ resolveOnly: ['./'], extensions: [...extensions, '.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: <my-addon>',
        replacement: path.resolve('src'),
      },
      {
        find: '<my-addon>/(.*)',
        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,
    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 = ['src/components/**/*.{js,ts}', 'src/services/*.{js,ts}'];

export default [
  defineConfig({
    input: 'src/index.ts',
    output: { ...addon.output(), entryFileNames: 'index.js' },
    plugins: [
      ...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.
      addon.appReexports(globallyAvailable),
    ],
  }),
  defineConfig({
    input: 'src/test-support/index.ts',
    output: { ...addon.output(), entryFileNames: 'test-support.js' },
    plugins: [
      ...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(['test-support/index.js']),
    ],
  }),
];
with babel

image

// @ts-nocheck
import path from 'path';

import alias from '@rollup/plugin-alias';
import ts from 'rollup-plugin-ts';
import { babel } from '@rollup/plugin-babel';
import { defineConfig } from 'rollup';
import { nodeResolve } from '@rollup/plugin-node-resolve';

import { Addon } from '@embroider/addon-dev/rollup';

import babelConfig from './babel.config';

const addon = new Addon({
  srcDir: 'src',
  destDir: 'dist',
});

const extensions = ['.js', '.ts'];

const transpilation = [
  // Instruct rollup how to follow import paths for typescript files
  // (in JS-only libraries, this isn't needed)
  nodeResolve({ resolveOnly: ['./'], extensions: [...extensions, '.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: <my-addon>',
        replacement: path.resolve('src'),
      },
      {
        find: '<my-addon>/(.*)',
        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!
  babel({ babelHelpers: 'bundled', extensions }),

  // 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 = ['src/components/**/*.{js,ts}', 'src/services/*.{js,ts}'];

export default [
  defineConfig({
    input: 'src/index.ts',
    output: { ...addon.output(), entryFileNames: 'index.js' },
    plugins: [
      ...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.
      addon.appReexports(globallyAvailable),
    ],
  }),
  defineConfig({
    input: 'src/test-support/index.ts',
    output: { ...addon.output(), entryFileNames: 'test-support.js' },
    plugins: [
      ...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(['test-support/index.js']),
    ],
  }),
];

Another notes about this setup:

for rollup-plugin-ts
related issue about babel config location

<addon-root>/
  - config/
    - babel.config.js
    - rollup.config.js 

for babel:

<addon-root>/
  - babel.config.js
  - config/
    - rollup.config.js 

For comparison, running tsc by itself is slow as well.

❯ yarn tsc --build
yarn run v1.22.17
$ <repo>/node_modules/.bin/tsc --build
Done in 8.16s.

So... I guess what's funny is that rollup-plugin-ts is faster than just running tsc alone. 😅

....so writing the ember-specific plugins for SWC would not get us that much benefit.

@NullVoxPopuli
Copy link
Collaborator Author

Closing, because the problem is typescript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant