-
Notifications
You must be signed in to change notification settings - Fork 19
Conversation
Two thoughts on this...
|
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.
minor documentation nits/improvements
README.md
Outdated
@@ -79,6 +80,33 @@ If the source file does not follow the pattern `create[custom element]Element`, | |||
dojo build webpack --element=src/path/to/element.ts --elementPrefix=the-special | |||
``` | |||
|
|||
### Feature optimization | |||
|
|||
This command supports the ability to optimize code based on statically asserted features. The tool can search the source code for modules that attempt to detect features using a [`@dojo/has`](https://github.com/dojo/has) type of API. By supplying a feature set (or sets) on the command line, the build will be optimized to optimize code branches, making the code smaller and slightly more efficient. This allows targeting of particular platforms. The tool will not optimize code, when specifying multiple feature sets, they do not align. It will instead continue to leave that feature to be detected at run-time. |
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 build will be optimized to optimize code branches, making the code smaller and slightly more efficient. -> the build will optimize code branches, making the code smaller and more efficient.
README.md
Outdated
@@ -79,6 +80,33 @@ If the source file does not follow the pattern `create[custom element]Element`, | |||
dojo build webpack --element=src/path/to/element.ts --elementPrefix=the-special | |||
``` | |||
|
|||
### Feature optimization | |||
|
|||
This command supports the ability to optimize code based on statically asserted features. The tool can search the source code for modules that attempt to detect features using a [`@dojo/has`](https://github.com/dojo/has) type of API. By supplying a feature set (or sets) on the command line, the build will be optimized to optimize code branches, making the code smaller and slightly more efficient. This allows targeting of particular platforms. The tool will not optimize code, when specifying multiple feature sets, they do not align. It will instead continue to leave that feature to be detected at run-time. |
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.
Move this to a separate paragraph and change "The tool will not optimize code, when specifying multiple feature sets, they do not align. It will instead continue to leave that feature to be detected at run-time." to "When specifying multiple feature sets, if they do not align, the tool will not optimize the source code for these feature sets and will instead continue to leave that feature to be detected at run-time."
README.md
Outdated
|`node`|This feature set represents Node.js 7+[<sup>2</sup>](#note-2)| | ||
|`safari`|This feature set represents Safari 10+[<sup>2</sup>](#note-2)| | ||
|
||
<span id="note-1">[1]:</span> Many of these features were present in earlier versions, but the specific version was the GA release at the time of writing when this was validated. |
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.
Maybe also say something to the effect that this isn't specific to Chrome 59+ or Opera 46+, and also supports browsers built on the same codebase such as Brave, Vivaldi, and perhaps Electron?
README.md
Outdated
|
||
From the command line, the feature sets are provided to the `-f` or `--feature` argument. The available feature sets are aligned to platforms. The currently available feature sets are: | ||
|
||
|Feature Set|Description| |
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.
People may not be impressed to learn that we have what they might think of a browser sniff testing rather than feature testing, so perhaps it's worth explaining a bit more how these feature test lists were created?
src/getFeatures.ts
Outdated
return {}; | ||
} | ||
|
||
// Reduce the array of loaded features to the largest set of features where the values don't |
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 -> do not
src/plugins/HasPlugin.ts
Outdated
const features = this._features; | ||
const dynamicFlags = new Set<string>(); | ||
|
||
// setup the dependencies for the subtitution |
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.
subtitution -> substitution
src/plugins/HasPlugin.ts
Outdated
compiler.plugin('compilation', (compilation, data) => { | ||
// and we want to hook the parser | ||
data.normalModuleFactory.plugin('parser', (parser) => { | ||
// we need direct access to the AST to properly figure out the has subtitution |
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.
subtitution -> substitution
src/plugins/util/walk.ts
Outdated
/** | ||
* Walk a estree AST tree | ||
* @param node The root estree Node to start walking | ||
* @param param1 An object with an `enter` and `leave` properties |
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.
with an -> with
This now requires dojo/shim#101 for the sets of features to actually be effective. |
src/plugins/util/walk.ts
Outdated
}); | ||
|
||
if (leave) { | ||
leave(node, parent, prop, index); |
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.
Probably not important, since it doesn't use shouldSkip
, but it feels like leave
should be called with the same context as enter
? Just for consistency maybe.
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.
Yeah, but we don't want people calling this.skip()
thinking that it would do something. So instead I have changed it to null
and annotated the this
in the types so that no one gets any bright ideas.
Type: feature
The following has been addressed in the PR:
Description:
This PR allows build optimization using the
has
feature detection library. During the build process, any static features that have been asserted are used to replace call expressions that look something likehas('feature')
. For example, if featurefoo
was set totrue
as a static flag, this code:Would be transformed to this:
Then further during the build process, if the build is being minified, uglify will detect the dead code and rewrite it further to something like:
At the command line, users are abstracted from individual flags, and instead supply a set of feature flags they wish to use. The supported sets are located in
src/features/*.json
. These are specified by the user by setting the-f
or--feature
flag on the CLI. Multiple feature sets are combined to produce the largest set where the values do not conflict. For examplees6-promise
istrue
onchrome
butfalse
onie11
. Ifchrome
andie11
were specified, the values would conflict and this feature would not be statically bound.A user supplying multiple platforms would look something like this:
Which would produce a build that is statically built with features that are common between Chrome, Safari, Firefox.
At the moment, most of the shim library isn't written to have polyfill code within
has()
guard blocks, therefore it doesn't get removed from the build when the native feature is statically expressed. We will need to revisit those modules in order to create something that builds optimally.Todo:
Resolves #142