Open joshuacc opened 11 years ago
I’ll take that under advisement. In the interim, if you’re using Google Closure Compiler, you might look into dead code elimination (tree shaking).
Can GCC remove dead code from prototypes?
It would be nicer to have a build script that takes a list of methods to shim and outputs a JS file with only those shims (and their dependencies).
You could then write something with https://github.com/substack/lexical-scope (or esprima directly) to scan a set of JS files and figure out which shims are needed.
This would be very cool as Browserify middleware (it could take a minimum supported target browserset too).
However, it might be difficult to tell usage of prototype methods (you'd need to find the runtime value of variables).
//cc @substack
@kriskowal Cool. Would you be interested in a pull request that breaks them out and then concatenates them with Grunt?
@joshuacc Not as such. If we go down this route, we’ll follow the path that @domenic and I are plotting at http://github.com/kriskowal/q, which is to say, we’ll not merely break and concat, but will entrain CommonJS dependency management and use Browserify or MontageJS’s Mr/Mrs/Mop to perform the concatenation. However, this might be a destabilizing change for some of ES5-Shim’s bigger stake-holders like Twitter, and I would expect them to weigh in.
But if it’s worth doing, you do not need my permission. You just might be signing up to maintain a fork.
I think this will be quite valuable, for example for Q. I envision a future where they are all provided as individual modules, perhaps with meta-modules for each object that needs work. So e.g. the main es5-shim does
require("./shims/array");
require("./shims/object");
require("./shims/function");
require("./shims/date");
// ...
and shims/array/index.js does
require("./map");
require("./reduce");
require("./filter");
// ...
and thus if you only needed Array.prototype.filter
and Object.keys
to work, e.g. in a library like Q, you'd do
require("es5-shim/shims/array/filter");
require("es5-shim/shims/object/keys");
We'd of course use Browserify's standalone ("UMD") support to maintain the status quo and thus nothing would actually change for consumers, besides this new ability to require individual files.
Alternately we could attempt to provide "uncurry-this'ed" versions, so e.g. you'd do
var filter = require("es5-shim/shims/array/filter");
filter(myArrayLike, ...);
But I think this is not really in the spirit of es5-shim, and if you want to do that, I believe lo-dash has you covered.
@domenic I would want to break these up in cohorts that are likely to need to be shimmed together, so maybe not quite so granular, but yes to everything else.
There is already some work undergoing about this
I'm sure there are other people that were frustrated and broke out subsets of ES5 shim into individual standalone modules.
@Raynos What is problem with copy-pasting or forking?
@Yaffle
What about using Square's es5 module transpiler?
I'm far more likely to use browserify, and require in each method as a separate shim.
+1
I've decided how I want to approach this - I'll be collating a list of 100% spec-compliant npm modules, one for each shim. Each module must be browserifiable, and VERY strong weight will be given to modules that are willing to grant ownership to the @es-shims Github organization, to ensure future maintenance and upkeep.
In parallel with this effort, I'll be working on a way to integrate browserify so that people can still include es5-shim.js
wholesale, but it will be composed of smaller pieces wherever possible.
In addition, in a future (major) release, I'd like to make require('es5-shim')
not do any active shimming or modification of the global env, but instead have a shim
method that will do so (and ideally each submodule will also have a shim
method). Part of the normal release a new version
workflow will still produce complete es5-shim.js
and es5-shim.min.js
files that auto-shim as they do now.
This will be a large, slow effort, but please feel free to make PRs to the shims.json
file I added in https://github.com/es-shims/es5-shim/commit/d24a08dfe81e0eda3d5e9f3b859d63c1da05aba7 so we can begin collaborating the list. I'll evaluate each one before accepting it.
var forEach = require('es5-shim/lib/for-each');
Extend native prototype like forEach.shim()
or require all shims like var allShims = require('es5-shim/lib')
and allShims.shim()
. And optionally provide a browserified version with umd inside in the dist
or root
dir.The advantage of making a separate module for each shim would be a shorter module name if people who own namespaces right now will free them, like var forEach = require('for-each')
. If you still need to write samething like require('es5-shim-for-each')
then its the same like var forEach = require('es5-shim/lib/for-each');
Also what about dependencies between shims? If you want to build them into one file you will need to include something like this https://github.com/kof/micro-modules I would love to see if it works for you!
That's a good point that they don't have to be separate shims, they can just be separate files. I'll work on that as well so that I can speed up the introduction of the build process.
However, separate small modules and repos imo is always better than one large one.
As for dependencies between shims - ideally, shims would have no dependencies (other than perhaps a shared ES5 helper module), and if they need interdependencies, we'll need to be careful not to create circular dependencies.
I suppose there will be dependencies between shims, not just helper functions. F.e. my animation frame shim implements Date.now and performance.now. Of course its a tiny dependency, but still it would be nicer to include them separately.
The more I think about separate repository for each shim, the more I like this idea. You could define dependencies in package.json and bower.json for each separately.
@ljharb I own github.com/Raynos/function-bind I added you as as a collaborater to it.
@Raynos thanks! i'll take a look and make sure all the spec edge cases are tested, and then i'll add it to the list.
+1. It will be very useful for the autopolyfiller
ps: https://github.com/azproduction/autopolyfiller-stable/issues/1
+1
+1, clear separation of concerns and modularized approach is definitely from which Browserifiable packages would benefit from.
I have tried to do a modular port using CommonJS and webpack
as bundler. Here's the file for Array.prototype.every
:
https://github.com/tomchentw-deprecated/holyfills/blob/master/lib/array/array_every.js
I'm interested to help on this. Any thoughts?
Most every shim already exists as a standalone, and standalones will need to follow a certain convention I've yet to lay out. The difficulty is in constructing a build process.
While I appreciate the offer of help, I'm already working on this. I'll update here as I make progress.
Personally I think that it should be solved in a Common.js way: we should use only the things that are require
d. A good example would be a module called es5-shim/array
that could be used like
var Array = require(`es5-shim/array`);
and it should contain all the internal stuff for browserify
to translate it into either a piece of JS with all the browser support or plain module.exports = Array
if there's no additional support needed.
Changing prototype
s or defining global variables has never been a good idea. That's not the way a shim should work at all.
Changing prototypes or defining global variables has never been a good idea. That's not the way a shim should work at all.
It works exactly as it should. Shim provides polyfill for standard APIs which are not supported in some browsers. Otherwise you'll end up using lodash/underscore-like APIs instead of native APIs
Hello there :-)
Is it something which is still under consideration? If so, what help is needed to move it forward?
@oncletom yes, it is. What I'm going to emulate is the process I've built in the es7-shim, but https://github.com/es-shims/es7-shim/issues/8 is a blocker before attempting that here. Please feel free to help on that issue on the es7-shim!
It would be awesome if the shims were provided as individual files so that I could easily use only the shims that are necessary for my particular project.