material-components / material-components-web

Modular and customizable Material Design UI components for the web
https://material.io/develop/web
MIT License
17.14k stars 2.14k forks source link

Export ES6 modules from dist directory #4722

Open moog16 opened 5 years ago

moog16 commented 5 years ago

related https://github.com/material-components/material-components-web/issues/4492#issuecomment-492226652

Feature request to generate ES6 modules from out TS files from within the /dist directory. This will help with GCC consumption.

rarous commented 5 years ago

I'm sorry, I was not clear in referred comment. This is not related to /dist but to the rest of the code in the package. Now it is mix of ES6 module system and classes transpiled to ES5 code. This ES5 code is the issue. Consumer already needs some traspiler to consume ES6 modules, so there is no need to transpile classes to ES5 code, because this is already not consumable by any ES5 interpreter.

For GCC compatibility it will help to have ES6 classes there.

rarous commented 5 years ago

After some investigation updating script build:esmodules in package.json with --target es6 should do the trick:

 "build:esmodules": "tsc --project ./tsconfig.json --target es6 --module esnext --importHelpers",
moog16 commented 5 years ago

@rarous I don't think you need to transpile our files in /dist. I tried this in my own HTML/CSS setup using checkbox, and just including @material/checkbox/dist/mdc.checkbox.js. I also ran use the es-check lib on the ES5 file. The transpile ES5 files are UMD, not ES6 so they should work in most browsers including IE11.

I'm fine with including ES6 modules with the stated build:esmodules... script you created, but I don't think your other statement is valid. Unless I am still misunderstanding something?

rarous commented 5 years ago

I'm not talking about /dist at all. It is bundle.

I'm interested in ES modules like @material/checkbox/component.js. Now they are mix of ES next modules (import .. from, export ...) with ES5 prototypes. Those can be ES6 classes.

moog16 commented 5 years ago

I forgot we also have those files (sorry). And I see what you're saying. This will be a breaking change, but it doesn't make sense to have them in ES5 since these files still need to go through transpilation.

I think we're on the same page now :)

rarous commented 5 years ago

True :)

It was unnecessary Breaking Change introduced in v1.0

kfranqueiro commented 5 years ago

https://github.com/material-components/material-components-web/issues/4222 explains why MDC Web provides ES6 modules with ES5 syntax. (In other words, there was a request just like this one, but in the opposite direction. Given that it was a change to provide code in a more widely-compatible format, I'm surprised it could end up being a breaking change...)

TL;DR:

You can consider additionally exporting modules with ES6 syntax, but the ES6-module-with-ES5-syntax-only was an intentional decision for these reasons, and should still be provided.

moog16 commented 5 years ago

@abhiomkar per ken's comment, it sounds like we should support both ES5 & ES6 with ES Modules support. I'm not sure how we want to organize this. Some things I've seen is appending the type to the file name such as component.es6.js and component.es5.js. We could also put this in the dist directory eg. dist/es6/component.js.

What are your thoughts?

abhiomkar commented 5 years ago

I agree to Ken's point that we would still need support ES6 modules with ES5 syntax. At this point I'm wondering if it is even worth to publish another version since it adds up to additional maintenance and bloats our component packages increasing download time for our clients.

WDYT?

I'm also curious to know GCC compatibility issue with ES5 syntax.

moog16 commented 5 years ago

Yes, we would need to add this file type, so it wouldn't be a breaking change for current users. It would technically increase developer's download times, but it would benefit users wanting to use ES6 as the file size would be smaller.

To your point it would add to our maintenance, but if I remember correctly mat-angular also provides es6 and es5. Most of this is automated too, so I doubt it will add a significant amount of maintenance.

Not sure of GCC compat issues. @rarous could you shed some light?

rarous commented 5 years ago

GCC needs more information to be Advanced mode consumable without breaking consumer code. Only annotation that GCC understands in current output is @constructor and there is no export of any other symbol. So when you use advanced mode compilation everything is munged, but differently in lib and app, because compiler doesn't know they are the same symbols.

GCC understands ES6 classes and exports so it has all informations to work as expected. This will not only help GCC but Rollup as well.

It's 2019, browsers support ES Modules and ES2017 syntax natively. Modern tooling also expects ES6+ and can it optimize more effectively. IMHO this should be default.

sgammon commented 5 years ago

@rarous in our case we want to build against MDC sources, and allow rewriting in the lib and app . if i understand correctly this issue would help with that, no? because we could include sources in our GCC build via ES6?

moog16 commented 5 years ago

Yes, this issue is to export ES6 classes along side the existing modules. So we would have UMD+ES5, ESM+ES5, and ESM+ES6.

sgammon commented 5 years ago

@moog16 thank you, that's fantastic. looking forward to it!

7iomka commented 4 years ago

I try to use your components with Next.js and have problem maybe related with type of package https://github.com/vercel/next.js/discussions/16805 Any help? Any ideas? Many thanks!

IgorNovozhilov commented 3 years ago

Hi, is there any work being done to solve this problem?

In my projects, I have to rebuild the packages every time, with the use of rollupjs. And the build settings come down to

src/material.js:

import './material.scss'
export * from 'material-components-web'

src/material.scss:

@use "material-components-web";

rollup.material.config.js:

import resolve from '@rollup/plugin-node-resolve'
import postcss from 'rollup-plugin-postcss'
import cleanup from 'rollup-plugin-cleanup'
import { terser } from 'rollup-plugin-terser'

export default [{
  input: 'src/material.js',
  treeshake: false,
  output: { file: 'material.js', format: 'esm', compact: true },
  plugins: [
    resolve({ browser: true, preferBuiltins: false }),
    postcss({ extract: true, minimize: true, use: [['sass', { includePaths: ['../node_modules'] }]] }),
    cleanup({ comments: 'none' }),
    terser()
  ]
}]