sprockets-commoner 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.nvmrc +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +3 -0
- data/README.md +205 -0
- data/Rakefile +10 -0
- data/circle.yml +13 -0
- data/js/babel-plugin-sprockets-commoner-internal/.gitignore +2 -0
- data/js/babel-plugin-sprockets-commoner-internal/README.md +24 -0
- data/js/babel-plugin-sprockets-commoner-internal/index.js +265 -0
- data/js/babel-plugin-sprockets-commoner-internal/package.json +14 -0
- data/js/babel-plugin-sprockets-commoner/README.md +3 -0
- data/js/babel-plugin-sprockets-commoner/index.js +7 -0
- data/js/babel-plugin-sprockets-commoner/package.json +5 -0
- data/lib/sprockets/commoner.rb +15 -0
- data/lib/sprockets/commoner/bundle.rb +57 -0
- data/lib/sprockets/commoner/processor.rb +174 -0
- data/lib/sprockets/commoner/railtie.rb +11 -0
- data/lib/sprockets/commoner/version.rb +5 -0
- data/sprockets-commoner.gemspec +37 -0
- metadata +185 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7be0d75114fb75a73b272d1493290b864cce8455
|
4
|
+
data.tar.gz: 3c98183d4ecfc9ab3824ece0acf091255f9df219
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6985592443fef03121a57c8a8e1f3c37e684a2fedb0561014f8c242f2629fccf6dc2f3c30789494b4a41eececaccde49424a40b858b7a7e11ad3c204093da44e
|
7
|
+
data.tar.gz: 16d3679cb215ca29fd2c8b1513cfb09704096ab31cf368ad42e5a7c8b6a41bbd13e3344ddfc0bbd89ee9f38119428f257ba3b4ab9749dec58dd896c2d3cf9307
|
data/.gitignore
ADDED
data/.nvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
v5.8.0
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at bouke@shopify.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
# Sprockets::Commoner
|
2
|
+
|
3
|
+
`Sprockets::Commoner` is a gem that enables JavaScript package and Babel transformation in Sprockets.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
* Compile JavaScript modules into a single bundle.
|
8
|
+
* Run Babel transforms.
|
9
|
+
* Easy setup. We adhere to the Rails Way™ and don't require any additional configuration for the simplest and most common set ups.
|
10
|
+
* Integrate tightly into Sprockets/Rails. You can use any of Sprockets' features like ERB inside your files without having to jump through crazy hoops.
|
11
|
+
* Designed to emit code that compresses incredibly well. The code generated will be smaller than webpack or browserify.
|
12
|
+
* Use `process.env` inside your JavaScript. This will also run on anything in `node_modules` (e.g. Babel), to ensure dependencies are also compressed optimally.
|
13
|
+
* Automatic deduplication of Babel helpers. No need to use `babel-runtime`, as commoner will automatically detect which helpers are used and share them between modules in a way that compressed very well.
|
14
|
+
|
15
|
+
## Setup
|
16
|
+
|
17
|
+
### Requirements
|
18
|
+
|
19
|
+
1. Ruby v2+.
|
20
|
+
2. Rails/Any other application that uses Sprockets.
|
21
|
+
2. NPM v3+. We only support version 3 because commoner doesn't do any sort of deduplication of dependencies, so you could end up with a huge bundle if you don't want out. We only test against version 3, so you will definitely run into issues when running version 2.
|
22
|
+
3. We recommend and support version 4+ of Node.js.
|
23
|
+
|
24
|
+
### 10-second simple set up
|
25
|
+
|
26
|
+
To get started, let's begin with the simplest possible set up: just enabling resolving of `require`.
|
27
|
+
|
28
|
+
1. Add `sprockets-commoner` to Gemfile, run `bundle install`, and restart your Rails server.
|
29
|
+
1. Add package.json with `babel-core` version 6 and any packages you want. For the example, we'll use the excellent [lodash](https://lodash.com) library. `npm install -S babel-core@6 lodash`
|
30
|
+
1. `require` your client-side JavaScript packages from `application.js`!
|
31
|
+
```
|
32
|
+
var _ = require('lodash');
|
33
|
+
|
34
|
+
console.log(_.map([1, 2, 3], function(n) { return n * 3; }));
|
35
|
+
```
|
36
|
+
|
37
|
+
### Enabling Babel transforms
|
38
|
+
|
39
|
+
1. Install any Babel plugins or presets you want to use. We'll use the default ES2015 preset; `npm install babel-preset-es2015`.
|
40
|
+
1. Add a `.babelrc` with you required configuration. We just need to do `echo '{presets: ["es2015"]}' > .babelrc`.
|
41
|
+
1. Use any feature you want! For example, let's use `import` and arrow functions in our `application.js`:
|
42
|
+
|
43
|
+
```
|
44
|
+
import {map} from 'lodash';
|
45
|
+
|
46
|
+
console.log(map([1, 2, 3], (n) => n * 3));
|
47
|
+
```
|
48
|
+
|
49
|
+
### Advanced configuration
|
50
|
+
|
51
|
+
#### Fine-tuned selection of files to process
|
52
|
+
|
53
|
+
By default, commoner will process any file under the application root directory. If you want more fine-tuned control over which files to process, you can specify which paths to include or exclude. To do so, you will need to re-register the Sprockets processor. For example:
|
54
|
+
|
55
|
+
```
|
56
|
+
# In config/initializers/sprockets_commoner.rb
|
57
|
+
Rails.application.config.assets.configure do |env|
|
58
|
+
env.unregister_postprocessor('application/javascript', Sprockets::Commoner::Processor)
|
59
|
+
env.register_postprocessor('application/javascript', Sprockets::Commoner::Processor.new(
|
60
|
+
env.root,
|
61
|
+
# include, exclude, and babel_exclude patterns can be path prefixes or regexes.
|
62
|
+
# Explicitely list paths to include. The default is `[env.root]`
|
63
|
+
include: ['app/assets/javascripts/subdirectory'],
|
64
|
+
# List files to ignore and not process require calls or apply any Babel transforms to. Default is empty.
|
65
|
+
exclude: [/ignored/],
|
66
|
+
# Anything listed in babel_exclude has its require calls resolved, but no transforms listed in .babelrcs applied.
|
67
|
+
# Default is [/node_modules/]
|
68
|
+
babel_exclude: [/node_modules/]
|
69
|
+
))
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
## Testing with Teaspoon
|
74
|
+
|
75
|
+
Teaspoon is not compatible with commoner by default. Under `test/demo` you can find a demo Rails application, containing a setup with Teaspoon. The key change is a custom boot partial and JavaScript file, found under `spec/javascripts/fixtures/teaspoon/suite`. Simply copy those two files under `fixtures/teaspoon/suite` in your JavaScript tests, make necessary changes to `boot.js.erb` to point to your test files, and you should be good to go.
|
76
|
+
|
77
|
+
## CoffeeScript interoperability
|
78
|
+
|
79
|
+
Commoner is designed from the start to facilitate a transition from CoffeeScript to ES2015.
|
80
|
+
|
81
|
+
### Importing CoffeeScript files
|
82
|
+
|
83
|
+
Any JavaScript file can `require` a CoffeeScript file, which will cause that CoffeeScript file to be scanned for a global variable reference and the `require` call to be replaced with a reference.
|
84
|
+
If we have the following two files:
|
85
|
+
|
86
|
+
```
|
87
|
+
# file.coffee
|
88
|
+
class window.ImportantClass
|
89
|
+
```
|
90
|
+
|
91
|
+
```
|
92
|
+
// main.js
|
93
|
+
var klass = require('./file');
|
94
|
+
|
95
|
+
new klass();
|
96
|
+
```
|
97
|
+
|
98
|
+
Then the second file will just be compiled down to `new window.ImportantClass()`. Importing global references works for global assignments and class definitions.
|
99
|
+
|
100
|
+
### Expose
|
101
|
+
|
102
|
+
We have added a custom directive that makes it very easy to expose an ES2015 module to the global namespace so it can be used by CoffeeScript files or any other code. For example:
|
103
|
+
|
104
|
+
```
|
105
|
+
'expose window.MyClass`;
|
106
|
+
|
107
|
+
export default class MyClass {}
|
108
|
+
```
|
109
|
+
|
110
|
+
`expose` will use the default export if available, otherwise the whole module namespace will be assigned to the global variable. For example:
|
111
|
+
|
112
|
+
```
|
113
|
+
// constants.js
|
114
|
+
'expose window.Constants';
|
115
|
+
|
116
|
+
export const A = 1;
|
117
|
+
export const B = 2;
|
118
|
+
export const C = 3;
|
119
|
+
```
|
120
|
+
|
121
|
+
This will make `window.Constants` equal `{A: 1, B: 2, C: 3}`.
|
122
|
+
|
123
|
+
## Methodology
|
124
|
+
|
125
|
+
Commoner registers a postprocessor that takes any `application/javascript` file and passes it through Babel.
|
126
|
+
|
127
|
+
### `require` support
|
128
|
+
|
129
|
+
`Sprockets::Commoner` enables support for `require()` by replacing `require` function calls with variable references. It does this by assigning every file a unique identifier based on their filename. For example, if the file you're referencing is located at `<root>/node_modules/package/index.js` it will get the name `__commoner_module__node_modules$package$index_js`. Any file that then `require`s this specific file will have that `require` call replaced with the identifier.
|
130
|
+
reference.
|
131
|
+
|
132
|
+
The Babel plugin also communicates back any files that were required to make sure they are included by Sprockets. `Sprockets::Commoner` depends on the topological ordering that Sprockets does to make sure any module that is needed is instantiated before it is used.
|
133
|
+
|
134
|
+
### Example
|
135
|
+
|
136
|
+
After the regular Babel plugins are done doing their thing, `babel-plugin-commoner-internal` kicks in, which is commoner's plugin that does the actual resolving. This plugin does the following things:
|
137
|
+
|
138
|
+
* It finds any `require` calls and rewires them to variable references (as detailed in [`require` support](#require-support))
|
139
|
+
* It wraps the module in a function and supplies it with `module` and `exports`. The end value of `module.exports` gets assigned to the module identifier, which is referenced by other files (as specified in '`require` support') Example:
|
140
|
+
|
141
|
+
```
|
142
|
+
var __commoner_module__node_modules$package$index_js = __commoner_initialize_module__(function (module, exports) {
|
143
|
+
exports.default = 123;
|
144
|
+
});
|
145
|
+
```
|
146
|
+
* If these is an expose directive at the top of the file, it assigns `module.exports` to the specified variable. For example, if the top of the file contains `'expose window.Whatever';` it will assign `exports.default` if there is a default, otherwise it just assigns `exports`. Therefore if our file has `expose window.Whatever` and no default, it will get `window.Whatever = exports;` appended to it.
|
147
|
+
|
148
|
+
#### Bundling
|
149
|
+
|
150
|
+
After all the files have been transformed, there is a bundle step which combines all of the processed JavaScript modules together. It then prepends an initializer function and all the Babel helpers (which are shared between all modules).
|
151
|
+
|
152
|
+
For example, if we have the following two files:
|
153
|
+
|
154
|
+
```
|
155
|
+
// module.js
|
156
|
+
export default function a() {
|
157
|
+
return 1;
|
158
|
+
};
|
159
|
+
```
|
160
|
+
|
161
|
+
```
|
162
|
+
// application.js
|
163
|
+
import a from './module';
|
164
|
+
|
165
|
+
a();
|
166
|
+
```
|
167
|
+
|
168
|
+
We will end up with the following (browser-runnable) file:
|
169
|
+
|
170
|
+
```
|
171
|
+
!function() {
|
172
|
+
var __commoner_initialize_module__ = function(f) {
|
173
|
+
var module = {exports: {}};
|
174
|
+
f.call(module.exports, module, module.exports);
|
175
|
+
return module.exports;
|
176
|
+
};
|
177
|
+
var global = window;
|
178
|
+
var __commoner_helper__interopRequireDefault = function (obj) {
|
179
|
+
return obj && obj.__esModule ? obj : {
|
180
|
+
default: obj
|
181
|
+
};
|
182
|
+
};
|
183
|
+
var __commoner_module__app$assets$javascripts$module_js = __commoner_initialize_module__(function (module, exports) {
|
184
|
+
"use strict";
|
185
|
+
|
186
|
+
Object.defineProperty(exports, "__esModule", {
|
187
|
+
value: true
|
188
|
+
});
|
189
|
+
exports.default = a;
|
190
|
+
function a() {
|
191
|
+
return 1;
|
192
|
+
};
|
193
|
+
});
|
194
|
+
var __commoner_module__app$assets$javascripts$application_js = __commoner_initialize_module__(function (module, exports) {
|
195
|
+
'use strict';
|
196
|
+
|
197
|
+
var _module2 = __commoner_helper__interopRequireDefault(__commoner_module__app$assets$javascripts$module_js);
|
198
|
+
|
199
|
+
(0, _module2.default)();
|
200
|
+
});
|
201
|
+
}();
|
202
|
+
```
|
203
|
+
|
204
|
+
This file is meant to be compressed, and does incredibly well when processed by UglifyJS.
|
205
|
+
|
data/Rakefile
ADDED
data/circle.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# babel-plugin-commoner
|
2
|
+
|
3
|
+
## Usage
|
4
|
+
|
5
|
+
`babel-plugin-commoner` should be included in your `.babelrc` by adding `commoner`. You can't install it through npm, but this directory is automatically added to the path by the Sprockets plugin.
|
6
|
+
|
7
|
+
## Options
|
8
|
+
|
9
|
+
* `globals`: A mapping of module name to global variable name, which will ovveride any import of that package with a global variable reference.
|
10
|
+
|
11
|
+
## Example
|
12
|
+
|
13
|
+
```json
|
14
|
+
{
|
15
|
+
presets: ["es2015"],
|
16
|
+
plugins: [
|
17
|
+
["commoner", {
|
18
|
+
globals: {
|
19
|
+
"jquery": "$"
|
20
|
+
}
|
21
|
+
}]
|
22
|
+
]
|
23
|
+
}
|
24
|
+
```
|
@@ -0,0 +1,265 @@
|
|
1
|
+
'use strict';
|
2
|
+
if (typeof Object.assign != 'function') {
|
3
|
+
(function () {
|
4
|
+
Object.assign = function (target) {
|
5
|
+
'use strict';
|
6
|
+
if (target === undefined || target === null) {
|
7
|
+
throw new TypeError('Cannot convert undefined or null to object');
|
8
|
+
}
|
9
|
+
|
10
|
+
var output = Object(target);
|
11
|
+
for (var index = 1; index < arguments.length; index++) {
|
12
|
+
var source = arguments[index];
|
13
|
+
if (source !== undefined && source !== null) {
|
14
|
+
for (var nextKey in source) {
|
15
|
+
if (source.hasOwnProperty(nextKey)) {
|
16
|
+
output[nextKey] = source[nextKey];
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
return output;
|
22
|
+
};
|
23
|
+
})();
|
24
|
+
}
|
25
|
+
|
26
|
+
var fs = require('fs');
|
27
|
+
var dirname = require('path').dirname;
|
28
|
+
var resolve = require('browser-resolve').sync;
|
29
|
+
|
30
|
+
module.exports = function (context) {
|
31
|
+
var t = context.types;
|
32
|
+
var exposeTemplate = context.template("$0 = exports['default'] != null ? exports['default'] : exports;");
|
33
|
+
|
34
|
+
var opts = null;
|
35
|
+
var rootRegex = null;
|
36
|
+
var identifierRegex = null;
|
37
|
+
|
38
|
+
function createIdentifierRegex() {
|
39
|
+
var globals = ['window'].concat(opts.globalNamespaces).map(function(namespace) {
|
40
|
+
return namespace + '\\.';
|
41
|
+
});
|
42
|
+
|
43
|
+
// Construct regex with prefixes which denote globals (like window.Something, @Something, or anything else in opts.globalNamespaces)
|
44
|
+
var globalObject = '(?:@|' + globals.join('|') + ')';
|
45
|
+
var validIdentifier = '[a-zA-Z][_a-zA-Z0-9]*';
|
46
|
+
// Look for identifiers that look like 'window.Something' or 'Shopify.Something'
|
47
|
+
var validAssignment = '(' + globalObject + validIdentifier + '(?:\\.' + validIdentifier + ')*)';
|
48
|
+
// Look for 'window.Something =' or 'class window.Something'
|
49
|
+
return '^(?:(?:' + validAssignment + '\\s*=)|(?:class ' + validAssignment + '))';
|
50
|
+
}
|
51
|
+
|
52
|
+
/*
|
53
|
+
* BIGGEST HACK OF __ALL_TIME__
|
54
|
+
* If we're requiring a CoffeeScript file, we're going to be assuming that we're assigning to the global namespace in that file.
|
55
|
+
* so, use a RegExp to find out that variable definition. (yep)
|
56
|
+
*/
|
57
|
+
function findDeclarationInCoffeeFile(path) {
|
58
|
+
var contents = fs.readFileSync(path);
|
59
|
+
var identifiers = [];
|
60
|
+
|
61
|
+
for (var regexp = new RegExp(identifierRegex, 'gm'), find = regexp.exec(contents); find != null; find = regexp.exec(contents)) {
|
62
|
+
identifiers.push(find[1] || find[2]);
|
63
|
+
}
|
64
|
+
|
65
|
+
if (identifiers.length === 0) {
|
66
|
+
throw new Error('No identifiers found in ' + path);
|
67
|
+
} else if (identifiers.length > 1) {
|
68
|
+
throw new Error('Multiple identifiers found in ' + path);
|
69
|
+
}
|
70
|
+
|
71
|
+
return identifiers[0].replace(/^@/, 'window.');
|
72
|
+
}
|
73
|
+
|
74
|
+
function isRequire(path) {
|
75
|
+
return path.isCallExpression() && path.get('callee').isIdentifier({ name: 'require' }) && !path.scope.hasBinding('require');
|
76
|
+
}
|
77
|
+
|
78
|
+
// Get the target path from a require call
|
79
|
+
function requireTarget(path) {
|
80
|
+
var evaluate = path.get('arguments')[0].evaluate();
|
81
|
+
if (!evaluate.confident || path.node.arguments.length !== 1) {
|
82
|
+
return null;
|
83
|
+
}
|
84
|
+
|
85
|
+
var target = evaluate.value;
|
86
|
+
if (typeof target !== 'string') {
|
87
|
+
throw new Error('Invalid require call, string expected');
|
88
|
+
}
|
89
|
+
return target;
|
90
|
+
}
|
91
|
+
|
92
|
+
// Find any 'expose <name>' directive and get back the value of '<name>'
|
93
|
+
function findExpose(directives) {
|
94
|
+
var result = void 0;
|
95
|
+
for (var i = 0; i < directives.length; i++) {
|
96
|
+
if (result = /^expose ([A-Za-z\.]+)$/.exec(directives[i].value.value)) {
|
97
|
+
directives.splice(i, 1);
|
98
|
+
return result[1];
|
99
|
+
}
|
100
|
+
}
|
101
|
+
return null;
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
// Transform a path into a variable name
|
106
|
+
function pathToIdentifier(path) {
|
107
|
+
var escapedPath = path.replace(rootRegex, '').replace(/[^a-zA-Z0-9_]/g, function (match) {
|
108
|
+
if (match === '/') {
|
109
|
+
return '$';
|
110
|
+
} else {
|
111
|
+
return '_';
|
112
|
+
}
|
113
|
+
});
|
114
|
+
return '__commoner_module__' + escapedPath;
|
115
|
+
}
|
116
|
+
|
117
|
+
function resolveTarget(file, path) {
|
118
|
+
var name = void 0;
|
119
|
+
if (opts.globals != null && (name = opts.globals[path]) != null) {
|
120
|
+
return name;
|
121
|
+
} else {
|
122
|
+
var resolvedPath = resolve(path, opts);
|
123
|
+
file.metadata.required.push(resolvedPath);
|
124
|
+
|
125
|
+
// Check if the path is under sourceRoot
|
126
|
+
var root = file.opts.sourceRoot;
|
127
|
+
if (!rootRegex.test(resolvedPath)) {
|
128
|
+
throw new Error("Cannot find module '" + path + "' from '" + dirname(file.opts.filename) + "' under '" + root + "'");
|
129
|
+
}
|
130
|
+
|
131
|
+
if (/\.coffee$/.test(resolvedPath)) {
|
132
|
+
// If it's a coffee script file, look for global variable assignments
|
133
|
+
return findDeclarationInCoffeeFile(resolvedPath);
|
134
|
+
} else {
|
135
|
+
// Otherwise we just look for the module by referencing its Special Identifier™
|
136
|
+
return pathToIdentifier(resolvedPath);
|
137
|
+
}
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
var callRewriter = {
|
142
|
+
VariableDeclarator: function VariableDeclarator(path, state) {
|
143
|
+
var init = path.get('init');
|
144
|
+
if (!isRequire(init)) {
|
145
|
+
return;
|
146
|
+
}
|
147
|
+
var binding = path.scope.getBinding(path.node.id.name);
|
148
|
+
if (!binding.constant) {
|
149
|
+
return;
|
150
|
+
}
|
151
|
+
|
152
|
+
var target = requireTarget(init);
|
153
|
+
if (target == null) {
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
|
157
|
+
var name = resolveTarget(state.file, target);
|
158
|
+
path.scope.rename(name);
|
159
|
+
path.scope.rename(path.node.id.name, name);
|
160
|
+
path.remove();
|
161
|
+
},
|
162
|
+
CallExpression: function CallExpression(path, state) {
|
163
|
+
if (!isRequire(path)) {
|
164
|
+
return;
|
165
|
+
}
|
166
|
+
|
167
|
+
var target = requireTarget(path);
|
168
|
+
if (target == null) {
|
169
|
+
return;
|
170
|
+
}
|
171
|
+
|
172
|
+
var replacement = resolveTarget(state.file, target);
|
173
|
+
switch (path.parent.type) {
|
174
|
+
case "ExpressionStatement":
|
175
|
+
// We just need to know there's a dependency, we can remove it then
|
176
|
+
path.remove();
|
177
|
+
break;
|
178
|
+
default:
|
179
|
+
// Otherwise we just look for the module by referencing its Special Identifier™
|
180
|
+
path.replaceWith(t.identifier(replacement));
|
181
|
+
break;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
};
|
185
|
+
|
186
|
+
return {
|
187
|
+
pre: function pre(file) {
|
188
|
+
if (file.metadata.required == null) {
|
189
|
+
file.metadata.required = [];
|
190
|
+
}
|
191
|
+
},
|
192
|
+
|
193
|
+
visitor: {
|
194
|
+
MemberExpression: function MemberExpression(path) {
|
195
|
+
if (path.get("object").matchesPattern("process.env")) {
|
196
|
+
var key = path.toComputedKey();
|
197
|
+
if (t.isStringLiteral(key)) {
|
198
|
+
path.replaceWith(t.valueToNode(process.env[key.value]));
|
199
|
+
}
|
200
|
+
}
|
201
|
+
},
|
202
|
+
UnaryExpression: function UnaryExpression(path) {
|
203
|
+
if (!path.node.operator === 'typeof') {
|
204
|
+
return;
|
205
|
+
}
|
206
|
+
|
207
|
+
var argument = path.get('argument');
|
208
|
+
if (!path.get('argument').isIdentifier()) {
|
209
|
+
return;
|
210
|
+
}
|
211
|
+
|
212
|
+
var name = path.node.argument.name;
|
213
|
+
if (name !== 'module' && name !== 'exports') {
|
214
|
+
return;
|
215
|
+
}
|
216
|
+
|
217
|
+
if (path.scope.hasBinding(name)) {
|
218
|
+
return;
|
219
|
+
}
|
220
|
+
|
221
|
+
path.replaceWith(t.stringLiteral('object'));
|
222
|
+
},
|
223
|
+
Program: {
|
224
|
+
exit: function exit(path, state) {
|
225
|
+
// Get options from commoner-options and merge them with the options
|
226
|
+
// that were passed to this plugin in .babelrc
|
227
|
+
opts = {
|
228
|
+
globalNamespaces: [],
|
229
|
+
// We can get these from Sprockets
|
230
|
+
extensions: ['.js', '.json', '.coffee', '.js.erb', '.coffee.erb']
|
231
|
+
};
|
232
|
+
|
233
|
+
// Look for the sprockets-commoner plugin for extra options
|
234
|
+
state.file.opts.plugins.map(function (plugin) {
|
235
|
+
return plugin[1];
|
236
|
+
}).filter(function (opts) {
|
237
|
+
return opts != null && opts.__commoner_options;
|
238
|
+
}).forEach(function (plugin) {
|
239
|
+
return Object.assign(opts, plugin);
|
240
|
+
});
|
241
|
+
|
242
|
+
Object.assign(opts, state.opts, { basedir: dirname(state.file.opts.filename) });
|
243
|
+
rootRegex = new RegExp('^' + state.file.opts.sourceRoot + '/');
|
244
|
+
identifierRegex = createIdentifierRegex();
|
245
|
+
|
246
|
+
// Signal back to Sprockets that we're rewiring
|
247
|
+
state.file.metadata.commonerEnabled = true;
|
248
|
+
|
249
|
+
var node = path.node;
|
250
|
+
var identifier = pathToIdentifier(state.file.opts.filename);
|
251
|
+
var expose = findExpose(node.directives);
|
252
|
+
if (expose != null) {
|
253
|
+
node.body.push(exposeTemplate(t.identifier(expose)));
|
254
|
+
}
|
255
|
+
|
256
|
+
// Transform module to a variable assignment.
|
257
|
+
// This variable is then referenced by any dependant children.
|
258
|
+
node.body = [t.variableDeclaration('var', [t.variableDeclarator(t.identifier(identifier), t.callExpression(t.identifier('__commoner_initialize_module__'), [t.functionExpression(null, [t.identifier('module'), t.identifier('exports')], t.blockStatement(node.body, node.directives))]))])];
|
259
|
+
node.directives = [];
|
260
|
+
path.traverse(callRewriter, state);
|
261
|
+
}
|
262
|
+
}
|
263
|
+
}
|
264
|
+
};
|
265
|
+
};
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
"name": "babel-plugin-sprockets-commoner-internal",
|
3
|
+
"private": true,
|
4
|
+
"description": "Find require calls and resolve the library they're calling.",
|
5
|
+
"scripts": {
|
6
|
+
"test": "NODE_ENV=test mocha"
|
7
|
+
},
|
8
|
+
"devDependencies": {
|
9
|
+
"babel-core": "^6.2.1",
|
10
|
+
"babel-plugin-transform-es2015-arrow-functions": "^6.5.2",
|
11
|
+
"babel-plugin-transform-es2015-modules-commonjs": "^6.2.1",
|
12
|
+
"mocha": "^2.3.4"
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'sprockets'
|
2
|
+
require 'sprockets/commoner/processor'
|
3
|
+
require 'sprockets/commoner/bundle'
|
4
|
+
|
5
|
+
module Sprockets
|
6
|
+
module Commoner
|
7
|
+
end
|
8
|
+
|
9
|
+
register_postprocessor 'application/javascript', ::Sprockets::Commoner::Processor
|
10
|
+
register_bundle_metadata_reducer 'application/javascript', :commoner_enabled, false, :|
|
11
|
+
register_bundle_metadata_reducer 'application/javascript', :commoner_used_helpers, Set.new, :+
|
12
|
+
register_bundle_processor 'application/javascript', ::Sprockets::Commoner::Bundle
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'sprockets/commoner/railtie' if defined?(Rails)
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'schmooze'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
module Commoner
|
5
|
+
class Bundle < Schmooze::Base
|
6
|
+
dependencies generator: 'babel-generator.default',
|
7
|
+
babelHelpers: 'babel-helpers',
|
8
|
+
t: 'babel-types'
|
9
|
+
|
10
|
+
method :generate_helpers, <<-JS
|
11
|
+
function(helpers) {
|
12
|
+
if (helpers.length === 0) {
|
13
|
+
return '';
|
14
|
+
}
|
15
|
+
var declaration = t.variableDeclaration('var',
|
16
|
+
helpers.map(function(helper) {
|
17
|
+
return t.variableDeclarator(t.identifier('__commoner_helper__' + helper), babelHelpers.get(helper));
|
18
|
+
})
|
19
|
+
);
|
20
|
+
return generator(declaration).code;
|
21
|
+
}
|
22
|
+
JS
|
23
|
+
|
24
|
+
PRELUDE = <<-JS.freeze
|
25
|
+
!function() {
|
26
|
+
var __commoner_initialize_module__ = function(f) {
|
27
|
+
var module = {exports: {}};
|
28
|
+
f.call(module.exports, module, module.exports);
|
29
|
+
return module.exports;
|
30
|
+
};
|
31
|
+
var global = window;
|
32
|
+
JS
|
33
|
+
|
34
|
+
OUTRO = <<-JS.freeze
|
35
|
+
|
36
|
+
}();
|
37
|
+
JS
|
38
|
+
def self.instance(env)
|
39
|
+
@instance ||= new(env.root)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.call(input)
|
43
|
+
instance(input[:environment]).call(input)
|
44
|
+
end
|
45
|
+
|
46
|
+
def call(input)
|
47
|
+
return unless input[:metadata][:commoner_enabled]
|
48
|
+
|
49
|
+
used_helpers = input[:metadata][:commoner_used_helpers]
|
50
|
+
helpers = generate_helpers(used_helpers.to_a)
|
51
|
+
{
|
52
|
+
data: "#{PRELUDE}#{helpers}\n#{input[:data]}#{OUTRO}"
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'schmooze'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module Sprockets
|
5
|
+
module Commoner
|
6
|
+
class Processor < Schmooze::Base
|
7
|
+
BABELRC_FILE = '.babelrc'.freeze
|
8
|
+
PACKAGE_JSON = 'package.json'.freeze
|
9
|
+
JS_PACKAGE_PATH = File.expand_path('../../../js', __dir__)
|
10
|
+
ALLOWED_EXTENSIONS = /\.js(?:\.erb)?\z/
|
11
|
+
|
12
|
+
dependencies babel: 'babel-core', commoner: 'babel-plugin-sprockets-commoner-internal'
|
13
|
+
|
14
|
+
method :version, 'function() { return [process.version, babel.version]; }'
|
15
|
+
method :transform, %q{function(code, opts, commonerOpts) {
|
16
|
+
try {
|
17
|
+
var file = new babel.File(opts);
|
18
|
+
|
19
|
+
// The actual helpers are generated in bundle.rb
|
20
|
+
file.set("helperGenerator", function(name) { return babel.types.identifier('__commoner_helper__' + name); });
|
21
|
+
|
22
|
+
var commonerPlugin = babel.OptionManager.normalisePlugin(commoner);
|
23
|
+
file.buildPluginsForOptions({plugins: [[commonerPlugin, commonerOpts]]});
|
24
|
+
|
25
|
+
return file.wrap(code, function () {
|
26
|
+
file.addCode(code);
|
27
|
+
file.parseCode(code);
|
28
|
+
return file.transform();
|
29
|
+
});
|
30
|
+
} catch (err) {
|
31
|
+
if (err.codeFrame != null) {
|
32
|
+
err.message += "\n";
|
33
|
+
err.message += err.codeFrame;
|
34
|
+
}
|
35
|
+
throw err;
|
36
|
+
}
|
37
|
+
}}
|
38
|
+
def self.instance(env)
|
39
|
+
@instance ||= new(env.root)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.call(input)
|
43
|
+
instance(input[:environment]).call(input)
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :include, :exclude, :babel_exclude
|
47
|
+
def initialize(root, include: [root], exclude: [], babel_exclude: [/node_modules/])
|
48
|
+
@include = include.map {|path| expand_to_root(path, root) }
|
49
|
+
@exclude = exclude.map {|path| expand_to_root(path, root) }
|
50
|
+
@babel_exclude = babel_exclude.map {|path| expand_to_root(path, root) }
|
51
|
+
super(root, 'NODE_PATH' => JS_PACKAGE_PATH)
|
52
|
+
end
|
53
|
+
|
54
|
+
def call(input)
|
55
|
+
@cache_key ||= [
|
56
|
+
self.class.name,
|
57
|
+
version,
|
58
|
+
VERSION,
|
59
|
+
].freeze
|
60
|
+
|
61
|
+
filename = input[:filename]
|
62
|
+
|
63
|
+
return unless should_process?(filename)
|
64
|
+
|
65
|
+
@env = input[:environment]
|
66
|
+
@required = input[:metadata][:required].to_a
|
67
|
+
insertion_index = @required.index(input[:uri]) || -1
|
68
|
+
@dependencies = Set.new(input[:metadata][:dependencies])
|
69
|
+
|
70
|
+
|
71
|
+
babel_config = babelrc_data(filename)
|
72
|
+
|
73
|
+
result = input[:cache].fetch([filename, @cache_key, input[:data], babel_config]) do
|
74
|
+
transform(input[:data], options(input), paths: @env.paths)
|
75
|
+
end
|
76
|
+
|
77
|
+
if result['metadata'].has_key?('required')
|
78
|
+
result['metadata']['required'].each do |r|
|
79
|
+
asset = resolve(r, accept: input[:content_type], pipeline: :self)
|
80
|
+
@required.insert(insertion_index, asset)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
{
|
85
|
+
data: result['code'],
|
86
|
+
dependencies: @dependencies,
|
87
|
+
required: Set.new(@required),
|
88
|
+
|
89
|
+
commoner_used_helpers: Set.new(input[:metadata][:commoner_used_helpers]) + result['metadata']['usedHelpers'],
|
90
|
+
commoner_enabled: input[:metadata][:commoner_enabled] | result['metadata']['commonerEnabled'],
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
def expand_to_root(path, root)
|
96
|
+
if path.is_a?(String)
|
97
|
+
File.expand_path(path, root)
|
98
|
+
else
|
99
|
+
path
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def should_process?(filename)
|
104
|
+
return false unless ALLOWED_EXTENSIONS =~ filename
|
105
|
+
return false unless self.include.empty? || match_any?(self.include, filename)
|
106
|
+
return false if match_any?(self.exclude, filename)
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
def match_any?(patterns, filename)
|
111
|
+
patterns.any? { |pattern| pattern_match(pattern, filename) }
|
112
|
+
end
|
113
|
+
|
114
|
+
def pattern_match(pattern, filename)
|
115
|
+
if pattern.is_a?(String)
|
116
|
+
filename.start_with?(pattern)
|
117
|
+
else
|
118
|
+
pattern === filename
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def babelrc_data(filename)
|
123
|
+
while filename != (filename = File.dirname(filename))
|
124
|
+
begin
|
125
|
+
name = File.join(filename, BABELRC_FILE)
|
126
|
+
data = File.read(name)
|
127
|
+
depend_on_file(name)
|
128
|
+
return data
|
129
|
+
rescue Errno::ENOENT
|
130
|
+
name = File.join(filename, PACKAGE_JSON)
|
131
|
+
data = package_babel_data(name)
|
132
|
+
if data
|
133
|
+
depend_on_file(name)
|
134
|
+
return JSON.dump(data)
|
135
|
+
else
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
return nil
|
141
|
+
end
|
142
|
+
|
143
|
+
def package_babel_data(filename)
|
144
|
+
return JSON.parse(File.read(filename))['babel']
|
145
|
+
rescue Errno::ENOENT
|
146
|
+
return nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def options(input)
|
150
|
+
# TODO(bouk): Fix sourcemaps. Sourcemaps are only available in Sprockets v4
|
151
|
+
{
|
152
|
+
'ast' => false,
|
153
|
+
'babelrc' => !match_any?(self.babel_exclude, input[:filename]),
|
154
|
+
'filename' => input[:filename],
|
155
|
+
'filenameRelative' => PathUtils.split_subpath(input[:load_path], input[:filename]),
|
156
|
+
'moduleRoot' => nil,
|
157
|
+
'sourceRoot' => @env.root,
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
def resolve(path, **kargs)
|
162
|
+
uri, deps = @env.resolve!(path, load_paths: [@env.root], **kargs)
|
163
|
+
@dependencies.merge(deps)
|
164
|
+
uri
|
165
|
+
end
|
166
|
+
|
167
|
+
def depend_on_file(path)
|
168
|
+
uri, deps = @env.resolve!(path, load_paths: [@env.root])
|
169
|
+
@dependencies.merge(deps)
|
170
|
+
uri
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Sprockets
|
2
|
+
module Commoner
|
3
|
+
class Railtie < ::Rails::Railtie
|
4
|
+
initializer 'sprockets-commoner' do
|
5
|
+
# We need to disable debugging because otherwise Rails will include each file individually, while we need everything to be bundled up together into a single file.
|
6
|
+
config.assets.debug = false
|
7
|
+
config.assets.paths << 'node_modules'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sprockets/commoner/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sprockets-commoner"
|
8
|
+
spec.version = Sprockets::Commoner::VERSION
|
9
|
+
spec.authors = ["Bouke van der Bijl"]
|
10
|
+
spec.homepage = 'https://github.com/Shopify/sprockets-commoner'
|
11
|
+
spec.email = ["bouke@shopify.com"]
|
12
|
+
spec.license = 'MIT'
|
13
|
+
|
14
|
+
spec.summary = %q{Use Babel in Sprockets to compile modules for the browser}
|
15
|
+
spec.description = %q{Sprockets::Commoner uses Node.JS to compile ES2015+ files to ES5 using Babel directly from NPM, without vendoring it.}
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# delete this section to allow pushing this gem to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|script|js\/babel-plugin-sprockets-commoner-internal\/test)/}) }
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
spec.add_dependency "sprockets", ">= 3", "< 4"
|
30
|
+
spec.add_dependency "schmooze", "~> 0.1.5"
|
31
|
+
|
32
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
33
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
34
|
+
spec.add_development_dependency "coffee-script", "~> 2.4"
|
35
|
+
spec.add_development_dependency "uglifier", "~> 2.7"
|
36
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sprockets-commoner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bouke van der Bijl
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sprockets
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '4'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '4'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: schmooze
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.1.5
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.1.5
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '10.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '10.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: minitest
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '5.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '5.0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: coffee-script
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '2.4'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '2.4'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: uglifier
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '2.7'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '2.7'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: pry
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.10'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0.10'
|
117
|
+
description: Sprockets::Commoner uses Node.JS to compile ES2015+ files to ES5 using
|
118
|
+
Babel directly from NPM, without vendoring it.
|
119
|
+
email:
|
120
|
+
- bouke@shopify.com
|
121
|
+
executables: []
|
122
|
+
extensions: []
|
123
|
+
extra_rdoc_files: []
|
124
|
+
files:
|
125
|
+
- ".gitignore"
|
126
|
+
- ".nvmrc"
|
127
|
+
- CODE_OF_CONDUCT.md
|
128
|
+
- Gemfile
|
129
|
+
- README.md
|
130
|
+
- Rakefile
|
131
|
+
- circle.yml
|
132
|
+
- js/babel-plugin-sprockets-commoner-internal/.gitignore
|
133
|
+
- js/babel-plugin-sprockets-commoner-internal/README.md
|
134
|
+
- js/babel-plugin-sprockets-commoner-internal/index.js
|
135
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/browser-resolve/LICENSE
|
136
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/browser-resolve/README.md
|
137
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/browser-resolve/empty.js
|
138
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/browser-resolve/index.js
|
139
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/browser-resolve/package.json
|
140
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/LICENSE
|
141
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/README.md
|
142
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/index.js
|
143
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/lib/async.js
|
144
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/lib/caller.js
|
145
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/lib/core.js
|
146
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/lib/core.json
|
147
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/lib/node-modules-paths.js
|
148
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/lib/sync.js
|
149
|
+
- js/babel-plugin-sprockets-commoner-internal/node_modules/resolve/package.json
|
150
|
+
- js/babel-plugin-sprockets-commoner-internal/package.json
|
151
|
+
- js/babel-plugin-sprockets-commoner/README.md
|
152
|
+
- js/babel-plugin-sprockets-commoner/index.js
|
153
|
+
- js/babel-plugin-sprockets-commoner/package.json
|
154
|
+
- lib/sprockets/commoner.rb
|
155
|
+
- lib/sprockets/commoner/bundle.rb
|
156
|
+
- lib/sprockets/commoner/processor.rb
|
157
|
+
- lib/sprockets/commoner/railtie.rb
|
158
|
+
- lib/sprockets/commoner/version.rb
|
159
|
+
- sprockets-commoner.gemspec
|
160
|
+
homepage: https://github.com/Shopify/sprockets-commoner
|
161
|
+
licenses:
|
162
|
+
- MIT
|
163
|
+
metadata:
|
164
|
+
allowed_push_host: https://rubygems.org
|
165
|
+
post_install_message:
|
166
|
+
rdoc_options: []
|
167
|
+
require_paths:
|
168
|
+
- lib
|
169
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - ">="
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
requirements: []
|
180
|
+
rubyforge_project:
|
181
|
+
rubygems_version: 2.5.1
|
182
|
+
signing_key:
|
183
|
+
specification_version: 4
|
184
|
+
summary: Use Babel in Sprockets to compile modules for the browser
|
185
|
+
test_files: []
|