-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Conversation
Codecov Report
@@ Coverage Diff @@
## feat/typescript #4435 +/- ##
===================================================
+ Coverage 99.05% 99.05% +<.01%
===================================================
Files 130 130
Lines 6238 6239 +1
Branches 813 813
===================================================
+ Hits 6179 6180 +1
Misses 58 58
Partials 1 1
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After starting to look through this PR, I think we should leave the Getting Started guide for a separate PR, if we touch it at all. The most important question is, will it continue to work as-is? (Since that's the entire point of us continuing to build the ESM where the ES2015+ source files used to reside.)
I'm concerned that the Getting Started guide becomes even more overwhelming and complicated than it already is, and if someone's interested in writing TS themselves, I feel like there should be separate resources for that beyond the scope of our repository.
@@ -1,179 +0,0 @@ | |||
<!--docs: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure we should remove this file...?
I had already updated this in an attempt to filter it down to things that still seemed relevant.
@acdvorak does this file still have merit for purposes of avoiding breakages when we mirror code internally? For that matter is there any stuff missing here that should be noted? (Or is anything that was notable in here present in best_practices.md?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well if we want to keep this as a best practices for writing foundations/adapter/components with TypeScript that makes sense. But a lot of this seems to be covered in the authoring-components.md
. What do you think?
docs/getting-started.md
Outdated
@@ -149,7 +149,7 @@ And open http://localhost:8080 in a browser. You should see a blue “Hello Worl | |||
Now that you have webpack configured to compile Sass into CSS, let's include the Sass files for the Material Design button. First install the Node dependency: | |||
|
|||
``` | |||
npm install --save-dev @material/button |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't remove --save-dev
. I'm pretty sure I stopped someone from doing this before (or had them revert it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we telling people to add their non-build step deps to devDeps? dependencies
are modules which are also required at runtime.
docs/getting-started.md
Outdated
You can install all of them by running this command: | ||
|
||
``` | ||
npm install --save-dev babel-core@6 babel-loader@7 babel-preset-es2015 babel-plugin-transform-object-assign | ||
npm install --save-dev babel-core@6 babel-loader@7 babel-preset-es2015 babel-plugin-transform-object-assign [email protected] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should typescript also be installed locally? It's not in this list...
Also, babel-plugin-transform-object-assign should no longer be needed (we should test that - I'm pretty sure all instances of Object.assign should no longer exist on the feat/typescript branch)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm...ya i suppose it should. Below I also recommend installing globally, but it should be included in their deps in package.json
All 624 screenshot tests passed for commit efdd684 vs. |
All 624 screenshot tests passed for commit 7d9fed4 vs. |
All 624 screenshot tests passed for commit c5206d7 vs. |
All 624 screenshot tests passed for commit 9963010 vs. |
All 624 screenshot tests passed for commit 380bdd0 vs. |
docs/importing-js.md
Outdated
Note that in this case, you must ensure your build toolchain is configured to process and transpile MDC Web's modules | ||
as well as your own. You will also need to include babel's | ||
[`transform-object-assign`](https://www.npmjs.com/package/babel-plugin-transform-object-assign) plugin for IE 11 support. | ||
|
||
See the [Getting Started guide](getting-started.md) for more details on setting up an environment. | ||
|
||
#### TypeScript | ||
|
||
If you are using TypeScript, MDC Web's packages also include `.d.ts` files for your consumption. Most of the time you shouldn't need to reference these, as the TypeScript compiler should automatically pick them up. MDC Web has also defined the `types` property found in `package.json`, for your convinence. There is a bundled `.d.ts` file found under the `dist` directory that maps to the respective UMD module. There are corresponding `.d.ts` files for each foundation/component/adapter/etc. within the package. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spelling: convinence
. Also, what does "for your convenience" mean? Why is the types
property important; what does it do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I read this doc again: https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html
It reads, "Also note that if your main declaration file is named index.d.ts and lives at the root of the package (next to index.js) you do not need to mark the "types" property, though it is advisable to do so."
I've been reading this incorrectly, and its actually required in our case. I'll update the wording.
docs/authoring-components.md
Outdated
setToggleColorTextContent: (/* textContent: string */) => {}, | ||
registerInteractionHandler: (/* type: string, handler: EventListener */) => {}, | ||
deregisterInteractionHandler: (/* type: string, handler: EventListener */) => {} | ||
setAttr: (/* attr: string, value: string */) => undefined, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace Closure Doc comments with TypeScript
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replaced it with:
getAttr: (attr: string) => '',
setAttr: (attr: string, value: string) => undefined,
addClass: (className: string) => undefined,
removeClass: (className: string) => undefined,
setToggleColorTextContent: (textContent: string) => undefined,
registerInteractionHandler: (type: string, handler: EventListener) => undefined,
deregisterInteractionHandler: (type: string, handler: EventListener) => undefined
Although in our actual implementation we don't have unused arguments. Should I just remove them to look like:
getAttr: () => '',
setAttr: () => undefined,
addClass: () => undefined,
removeClass: () => undefined,
setToggleColorTextContent: () => undefined,
registerInteractionHandler: () => undefined,
deregisterInteractionHandler: () => undefined,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would probably leave them to make it clear that they exist, even if we're not using them.
All 624 screenshot tests passed for commit aa80f74 vs. |
We can probably update |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few small wording suggestions, but otherwise LGTM!
docs/authoring-components.md
Outdated
├── constants.js # The component's cssClasses/strings/numbers constants | ||
├── foundation.js # The component's foundation class | ||
├── index.js # The file that contains the vanilla component class, as well as exports the foundation | ||
├── adapter.ts # The adapter interface implemented by the component |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Adapter interface implemented by framework wrappers and the vanilla component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were some of Andy's comments not resolved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just about to fix these. I didn't see this yesterday.
docs/authoring-components.md
Outdated
├── foundation.js # The component's foundation class | ||
├── index.js # The file that contains the vanilla component class, as well as exports the foundation | ||
├── adapter.ts # The adapter interface implemented by the component | ||
├── foundation.ts # The component's foundation class |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Framework-agnostic business logic used by wrapper libraries and the vanilla component
docs/authoring-components.md
Outdated
@@ -478,9 +474,11 @@ A typical component within our codebase looks like so: | |||
packages | |||
├── mdc-component | |||
├── README.md # The component's README |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Usage instructions and API documentation
├── foundation.ts # The component's foundation class | ||
├── component.ts # The file that contains the vanilla component class | ||
├── constants.ts # The component's cssClasses/strings/numbers constants | ||
├── index.ts # The file that exports the source files of the package (foundation, component, adapter, constants, etc.) | ||
├── mdc-component.scss # The main source file for the component's CSS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add line items for types.ts
and util.ts
too. Be sure to mention that they're both optional.
All non-component-related types and interfaces not covered by other files should go in types.ts
.
util.ts
is for framework-agnostic helper functions (e.g., feature detection).
docs/authoring-components.md
Outdated
├── index.js # The file that contains the vanilla component class, as well as exports the foundation | ||
├── adapter.ts # The adapter interface implemented by the component | ||
├── foundation.ts # The component's foundation class | ||
├── component.ts # The file that contains the vanilla component class |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Vanilla adapter implementation for clients who aren't using a wrapper framework like React
docs/authoring-components.md
Outdated
├── adapter.ts # The adapter interface implemented by the component | ||
├── foundation.ts # The component's foundation class | ||
├── component.ts # The file that contains the vanilla component class | ||
├── constants.ts # The component's cssClasses/strings/numbers constants |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Constant values used by one or more files in the package (e.g., cssClasses, strings, numbers)
docs/authoring-components.md
Outdated
├── foundation.ts # The component's foundation class | ||
├── component.ts # The file that contains the vanilla component class | ||
├── constants.ts # The component's cssClasses/strings/numbers constants | ||
├── index.ts # The file that exports the source files of the package (foundation, component, adapter, constants, etc.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Re-exports types from other files in the package (adapter, foundation, component, util, etc.)
docs/importing-js.md
Outdated
@@ -26,12 +26,20 @@ of your built assets, you will want to explicitly reference the package's `index | |||
import {MDCFoo, MDCFooFoundation} from '@material/foo/index'; | |||
``` | |||
|
|||
Certain build tools will often pick up on the use of `package.json`'s `module` property, which points to the ES2015+ `index.js` source code. If you are using [Webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/guide/en), then you will not need to reference the `index.js` file, and can continue to use the `@material/foo` import paths. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certain build tools will detect the `module` property in `package.json`,
which points to ES2015+ source code in an `index.js` file.
If you're using [Webpack](https://webpack.js.org/) or
[Rollup](https://rollupjs.org/guide/en), you do not need to
reference `/index` directly, and can continue to use the shorter
`@material/foo` import path syntax.
(Reformat the above into one line)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this comment hasn't been applied.
Furthermore, index.js isn't ES2015+ source anymore. It's ES5 source in an ES module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you phrase "ES5 source in an ES module" in context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 2 index.js files of the npm package are:
dist/index.js (ES5) -- UMD
index.js (ES2015+) -- ESModule
Isn't what Andy wrote correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The distinction is that prior to the TS conversion, *.js was ES modules with ES2015+ syntax, thus requiring babel and additionally the object assign polyfill. After the TS conversion, *.js are ES modules with ES5 syntax. I believe that means you can get away with just webpack and not babel at all?
In terms of phrasing, something like: "which points to an ES module otherwise containing only ES5 syntax". We could link something to Rollup's pkg.module definition at https://github.com/rollup/rollup/wiki/pkg.module if we want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kfranqueiro I just checked by running npm run build:esmodules
, so I do think you're correct.
Also I just noticed that we don't use Object.assign
anywhere in our packages/
directory. I do not think you need babel for either of our UMD or ESM packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RE your last point, that's what I mean. Previously we were relying on the object assign polyfill to generate our UMD (you were never expected to need babel to consume those). Now we don't need to use that polyfill for our build process, and neither does anyone else using us within their own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In getting-started.md there is this dep:
- [babel-plugin-transform-object-assign](http://npmjs.org/package/babel-plugin-transform-object-assign), for IE 11 support
I am going to remove it
docs/authoring-components.md
Outdated
class RedblueToggle extends MDCComponent { | ||
initialize() { | ||
this.root.addEventListener('click', this.foundation_.handleClick); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can use this.listen
/ this.unlisten
here now that the class extends MDCComponent
docs/authoring-components.md
Outdated
├── constants.js # The component's cssClasses/strings/numbers constants | ||
├── foundation.js # The component's foundation class | ||
├── index.js # The file that contains the vanilla component class, as well as exports the foundation | ||
├── adapter.ts # The adapter interface implemented by the component |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were some of Andy's comments not resolved?
The following guidelines outline the general conventions for writing closure-friendly code for MDC Web. | ||
This section should contain most - if not all - of what you need to get up and running writing components in our codebase. | ||
|
||
### All `import` statements must _not_ use re-exported modules. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should effectively be moved to best_practices.md in the form of a heading explaining that in the context of component packages, only the index and component files are allowed to reference index
, because wrappers shouldn't need to pull in index
or component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this line still accurate?
This is an unfortunate side-effect of how closure's module naming mechanism works.
|
||
Using this convention allows us to write tooling around handling these expressions, such as lint rule exceptions. | ||
|
||
### For key/value maps, use index signatures where possible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be moved to best_practices.md; I added this specifically for TypeScript
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re both closure-compiler comments: I ended up adding this entire block:
#### All `import` statements must _not_ use re-exported modules
Only the `index.ts` or `component.ts` files are allowed to reference from other component packages' `index.ts`. This is because wrapping libraries only use `foundation` and `adapter`, so we should decouple the `component`.
```ts
// BAD
import {MDCFoundation} from '@material/base';
// GOOD
import {MDCFoundation} from '@material/base/foundation';
All adapters must be defined as interfaces
Each adapter must be defined within an adapter.ts
file in the component's package directory.
All methods should contain a summary of what they should do. This summary should be
copied over to the adapter API documentation in our README. This will facilitate future endeavors
to potentially automate the generation of our adapter API docs. Note that this replaces the
inline comments present in the methods within defaultAdapter
.
// adapter.ts
export interface MDCComponentAdapter {
/**
* Adds a class to the root element.
*/
addClass(className: string): void;
/**
* Removes a class from the root element.
*/
removeClass(className: string): void;
}
Foundation classes must extend MDCFoundation
Foundations must extend MDCFoundation
parameterized by their respective adapter. The
defaultAdapter
must return an object with the correct adapter shape.
// foundation.ts
import {MDCFoundation} from '@material/base/foundation';
import MDCComponentAdapter from './adapter';
export class MDCComponentFoundation extends MDCFoundation<MDCComponentAdapter> {
static get defaultAdapter(): MDCComponentAdapter {
return {
addClass: (className: string) => undefined,
removeClass: (className: string) => undefined,
};
}
}
Component classes must extend MDCComponent
Components must extend MDCComponent
parameterized by their respective foundation.
// index.ts
import {MDCComponent} from '@material/base/component';
import MDCComponentFoundation from './foundation';
export class MDCAwesomeComponent extends MDCComponent<MDCComponentFoundation> {
getDefaultFoundation(): MDCComponentFoundation {
return new MDCComponentFoundation({
addClass: (className: string) => this.root_.classList.add(className),
removeClass: (className: string) => this.root_.classList.remove(className),
});
}
}
For key/value maps, use index signatures where possible
Index signatures are useful for homogeneous maps of key/value pairs, while interfaces are useful for specific object signatures.
Both are more specific than just typing something as object
, and are thus preferable for their respective use cases.
static get strings(): {[key: string]: string} {
...
}
docs/importing-js.md
Outdated
@@ -26,12 +26,20 @@ of your built assets, you will want to explicitly reference the package's `index | |||
import {MDCFoo, MDCFooFoundation} from '@material/foo/index'; | |||
``` | |||
|
|||
Certain build tools will often pick up on the use of `package.json`'s `module` property, which points to the ES2015+ `index.js` source code. If you are using [Webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/guide/en), then you will not need to reference the `index.js` file, and can continue to use the `@material/foo` import paths. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this comment hasn't been applied.
Furthermore, index.js isn't ES2015+ source anymore. It's ES5 source in an ES module.
All 624 screenshot tests passed for commit 42e349b vs. |
All 624 screenshot tests passed for commit 160fd92 vs. |
All 624 screenshot tests passed for commit 0790186 vs. |
All 624 screenshot tests passed for commit 618d556 vs. |
All 624 screenshot tests passed for commit 72ce98f vs. |
All 624 screenshot tests passed for commit 7cd0007 vs. |
related #4225
I'm fairly certain I found all instances of
.js
that needed to be replaced to.ts
. I ignored all demos/tests since we aren't rewriting those just yet.TODO:
check-imports.js
script