Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

broccoli-es6-module-transpiler

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

broccoli-es6-module-transpiler - npm Package Compare versions

Comparing version 0.1.1 to 0.2.0

.travis.yml

373

index.js

@@ -1,69 +0,342 @@

var Filter = require('broccoli-filter');
var Compiler = require('es6-module-transpiler').Compiler;
'use strict';
module.exports = TranspilerFilter;
var fs = require('fs'),
path = require('path'),
util = require('util'),
mkdirp = require('mkdirp'),
quickTemp = require('quick-temp'),
walkSync = require('walk-sync'),
helpers = require('broccoli-kitchen-sink-helpers'),
Writer = require('broccoli-writer');
TranspilerFilter.prototype = Object.create(Filter.prototype);;
TranspilerFilter.prototype.constructor = TranspilerFilter;
var transpiler = require('es6-module-transpiler'),
Container = transpiler.Container,
FileResolver = transpiler.FileResolver,
Module = require('es6-module-transpiler/lib/module');
function TranspilerFilter(inputTree, options) {
if (!(this instanceof TranspilerFilter)) {
return new TranspilerFilter(inputTree, options);
}
module.exports = CompileModules;
options = options || {};
this.inputTree = inputTree;
this.type = 'amd';
// -- CompileModules -----------------------------------------------------------
for (var key in options) {
if (options.hasOwnProperty(key)) {
this[key] = options[key]
function CompileModules(inputTree, options) {
if (!(this instanceof CompileModules)) {
return new CompileModules(inputTree, options);
}
}
if (this.moduleName === true) {
this.moduleName = function(filePath) {
return filePath.slice(0, -3);
};
}
options || (options = {});
var formatter = options.formatter;
if (!formatter) {
formatter = transpiler.formatters.DEFAULT;
}
if (typeof formatter === 'string') {
formatter = transpiler.formatters[formatter];
}
this.inputTree = inputTree;
this.formatter = formatter;
this.output = options.output || '.';
this.description = options.description;
this._cache = {};
this._cacheIndex = 0;
}
TranspilerFilter.prototype.extensions = ['js'];
TranspilerFilter.prototype.targetExtension = 'js';
util.inherits(CompileModules, Writer);
TranspilerFilter.prototype.getModuleName = function(filePath) {
if (typeof this.moduleName === 'function') {
return this.moduleName(filePath);
} else {
return this.moduleName;
}
CompileModules.prototype.cleanup = function () {
quickTemp.remove(this, 'tmpCacheDir');
Writer.prototype.cleanup.apply(this, arguments);
};
TranspilerFilter.prototype.getTranspilerOptions = function(filePath) {
if (typeof this.transpilerOptions === 'function') {
return this.transpilerOptions(filePath);
} else {
return this.transpilerOptions;
}
CompileModules.prototype.getCacheDir = function () {
return quickTemp.makeOrReuse(this, 'tmpCacheDir');
};
TranspilerFilter.prototype.processString = function (fileContents, filePath) {
var name = this.getModuleName(filePath);
var options = this.getTranspilerOptions(filePath);
CompileModules.prototype.write = function (readTree, destDir) {
return readTree(this.inputTree).then(function (srcDir) {
var outputPath = path.join(destDir, this.output),
modules = [];
var compiler = new Compiler(fileContents, name, options);
function hash(filePaths) {
Array.isArray(filePaths) || (filePaths = [filePaths]);
try {
return compiler[transpilerMethods[this.type]]();
} catch(e) {
e.file = filePath;
throw e;
}
return filePaths.map(function (filePath) {
return hashFile(path.join(srcDir, filePath));
}).join(',');
}
walkSync(srcDir).forEach(function (relPath) {
// Keep track of all the JavaScript modules.
if (path.extname(relPath) === '.js') {
modules.push(relPath);
return;
}
// Skip doing anything with dir entries. When outputting a bundle
// format some dirs may go away. For non-JavaScript files, their
// containing dir will be created before they are copied over.
if (relPath.charAt(relPath.length - 1) === '/') {
return;
}
var srcPath = path.join(srcDir, relPath),
destPath = path.join(destDir, relPath);
// Copy over non-JavaScript files to the `destDir`.
//
// TODO: switch to `symlinkOrCopySync()` after:
// https://github.com/broccolijs/broccoli/issues/179
mkdirp.sync(path.dirname(destPath));
helpers.copyPreserveSync(srcPath, destPath);
});
var modulesToCompile = [],
cache = this._cache,
cacheEntry;
// The specificed `output` can either be a file (for bundle formatters),
// or a dir.
//
// When outputting to a single file, all the input files must must be
// unchanged in order to use the cached compiled file.
//
// When outputting to a dir, we symlink/copy over the cached compiled
// file for any modules that are unchanged. Any modified modules are
// added to the `modulesToCompile` collection.
if (path.extname(outputPath) === '.js') {
cacheEntry = cache[path.basename(outputPath)];
// Must hash _all_ modules when outputting to a single file.
if (cacheEntry && cacheEntry.hash === hash(modules)) {
this.copyFromCache(cacheEntry, path.dirname(outputPath));
} else {
// With a cache-miss, we need to re-generate the bundle output
// file, so we have to visit all the modules. The CacheResolver
// will make sure we don't have to read-and-parse the modules
// that are unchanged.
modulesToCompile = modules;
}
} else {
// Iterate over all the modules and copy compiled files from the
// cache for the ones that are unchanged.
modules.forEach(function (module) {
cacheEntry = cache[module];
if (cacheEntry && cacheEntry.hash === hash(module)) {
this.copyFromCache(cacheEntry, outputPath);
} else {
modulesToCompile.push(module);
}
}, this);
}
this.compileAndCacheModules(modulesToCompile, srcDir, outputPath);
}.bind(this));
};
var transpilerMethods = {
'amd': 'toAMD',
'yui': 'toYUI',
'cjs': 'toCJS',
'globals': 'toGlobals'
CompileModules.prototype.compileAndCacheModules = function (modulePaths, srcDir, outputPath) {
// Noop when no modules to compile.
if (modulePaths.length < 1) { return; }
var cache = this._cache,
outputIsFile = path.extname(outputPath) === '.js';
// The container will first use the CacheResolver so that any unchanged
// modules that need to be visited by the transpiler don't have to be
// re-read from disk or re-parsed.
//
// If "foo" imports "bar", and "bar" is unchanged, the transpiler still will
// need to vist it when re-processing "foo".
var container = new Container({
formatter: this.formatter,
resolvers: [
new CacheResolver(cache, srcDir),
new FileResolver([srcDir])
]
});
// Returns transpiler `Module` instances.
var modules = modulePaths.map(function (modulePath) {
return container.getModule(modulePath);
});
// Create a new cache sub-dir for this compile run.
var cacheDir = path.join(this.getCacheDir(), String(this._cacheIndex++));
// Determine target path to compile modules to.
var target = outputIsFile ?
path.join(cacheDir, path.basename(outputPath)) : cacheDir;
// Outputs the compiled modules to the cache.
mkdirp(target);
container.write(target);
var outputHash = [],
cacheEntry, outputFile;
modules.forEach(function (module) {
var hash = hashFile(module.path),
relPath = path.relative(srcDir, module.path),
modImports = module.imports,
modExports = module.exports;
// If the `module` was built with cached metadata, we want to un-wrap
// its `imports` and `exports` before storing them in the `cacheEntry`.
if (module instanceof CachedModule) {
modImports = Object.getPrototypeOf(modImports);
modExports = Object.getPrototypeOf(modExports);
}
// Adds an entry to the cache for the later use by the CacheResolver.
// This holds the parsed and walked AST, so re-builds of unchanged
// modules don't need to be re-read and re-parsed.
var cacheEntry = cache[relPath] = {
hash: hash,
ast : module.ast,
scope : module.scope,
imports: modImports,
exports: modExports
};
// Accumulate hashes if the final output is a single bundle file, and
// return early.
if (outputIsFile) {
outputHash.push(hash);
return;
}
// When outputting to a dir, add the compiled files to the cache entry
// and copy the files from the cache dir to the `outputPath`.
cacheEntry.dir = cacheDir;
cacheEntry.outputFiles = [
relPath,
relPath + '.map'
];
this.copyFromCache(cacheEntry, outputPath);
}, this);
if (outputIsFile) {
outputFile = path.basename(outputPath);
// Create a cache entry for the entire bundle output file and copy it
// from the cache to the `outputPath`.
cacheEntry = cache[outputFile] = {
hash: outputHash.join(','),
dir : cacheDir,
outputFiles: [
outputFile,
outputFile + '.map'
]
};
this.copyFromCache(cacheEntry, path.dirname(outputPath));
}
};
CompileModules.prototype.copyFromCache = function (cacheEntry, destDir) {
var cacheDir = cacheEntry.dir;
cacheEntry.outputFiles.forEach(function (outputFile) {
var cachePath = path.join(cacheDir, outputFile),
destPath = path.join(destDir, outputFile);
// TODO: switch to `symlinkOrCopySync()` after:
// https://github.com/broccolijs/broccoli/issues/179
mkdirp.sync(path.dirname(destPath));
helpers.copyPreserveSync(cachePath, destPath);
});
};
// -- CacheResolver ------------------------------------------------------------
// Used to speed up transpiling process on re-builds. The `cache` contains the
// `ast`s and other info from perviously read-and-parsed modules. This data can
// be reused for unchanged modules that the transpiler still needs to visit when
// it's compiling during a re-build.
function CacheResolver(cache, srcDir) {
this.cache = cache;
this.srcDir = srcDir;
}
CacheResolver.prototype.resolveModule = function (importedPath, fromModule, container) {
var resolvedPath = this.resolvePath(importedPath, fromModule),
cachedModule = container.getCachedModule(resolvedPath);
if (cachedModule) {
return cachedModule;
}
var cacheEntry = this.cache[path.relative(this.srcDir, resolvedPath)];
// Gets a file-stats hash of the module file, then checks if there's a cache
// entry with that hash.
if (cacheEntry && cacheEntry.hash === hashFile(resolvedPath)) {
return new CachedModule(resolvedPath, importedPath, container, cacheEntry);
}
return null;
};
CacheResolver.prototype.resolvePath = function (importedPath, fromModule) {
var srcDir = this.srcDir,
resolved;
if (importedPath.charAt(0) === '.' && fromModule) {
srcDir = path.dirname(fromModule.path);
}
resolved = path.resolve(srcDir, importedPath);
if (path.extname(resolved) !== '.js') {
resolved += '.js';
}
return resolved;
};
// -- CachedModule -------------------------------------------------------------
function CachedModule(resolvedPath, importedPath, container, cachedMeta) {
Module.call(this, resolvedPath, importedPath, container);
this.ast = cachedMeta.ast;
this.scope = cachedMeta.scope;
// Shadow cached `module` with `this`.
this.imports = Object.create(cachedMeta.imports, {
module: {value: this}
});
// Shadow cached `module` with `this`.
this.exports = Object.create(cachedMeta.exports, {
module: {value: this}
});
}
util.inherits(CachedModule, Module);
// -- Utilities ----------------------------------------------------------------
var hashFile = helpers.hashTree;
// TODO: Determine if this impl is needed after:
// https://github.com/broccolijs/broccoli/issues/179
//
// Wrapper around `hashTree()` to dereference symbolic links within the Broccoli
// build chain, so when new symlinks are created they won't be considered as
// changed files, unless the real file they are pointing to hashes differently.
// function hashFile(path) {
// if (fs.lstatSync(path).isSymbolicLink()) {
// path = fs.realpathSync(path);
// }
//
// return helpers.hashTree(path);
// }
{
"name": "broccoli-es6-module-transpiler",
"version": "0.1.1",
"version": "0.2.0",
"description": "Broccoli plugin for Square's ES6 Module Transpiler",

@@ -8,2 +8,5 @@ "main": "index.js",

"license": "MIT",
"contributors": [
"Eric Ferraiuolo <eferraiuolo@gmail.com>"
],
"repository": {

@@ -13,2 +16,5 @@ "type": "git",

},
"scripts": {
"test": "mocha tests/"
},
"keywords": [

@@ -18,3 +24,5 @@ "broccoli-plugin",

"es6",
"modules",
"module",
"compile",
"transpile",

@@ -25,5 +33,14 @@ "amd",

"dependencies": {
"broccoli-filter": "0.1.6",
"es6-module-transpiler": "~0.4.0"
"broccoli-kitchen-sink-helpers": "^0.2.4",
"broccoli-writer": "^0.1.1",
"es6-module-transpiler": "^0.6.0",
"mkdirp": "^0.5.0",
"quick-temp": "^0.1.2",
"walk-sync": "^0.1.2"
},
"devDependencies": {
"broccoli": "^0.12.3",
"expect.js": "^0.3.1",
"mocha": "^1.20.1"
}
}

83

README.md
# Broccoli's ES6 Module Transpiler
[![Build Status](https://travis-ci.org/mmun/broccoli-es6-module-transpiler.svg?branch=tests)](https://travis-ci.org/mmun/broccoli-es6-module-transpiler)
A Broccoli plugin that transpiles ES6 modules to other module types using
**Square's [es6-module-transpiler][transpiler]**.
**Note:** The `es6-module-transpiler` package underwent a major refactor _after_
`v0.4.0`, the previous version of this package that works with the older
transpiler is available on the [`transpiler-0.4` branch][prev-version].
## Usage
Transpiling to AMD:
### Transpiling to CommonJS
```javascript
var transpileES6 = require('broccoli-es6-module-transpiler');
var compileModules = require('broccoli-es6-module-transpiler');
var transpiledLib = transpileES6(lib, {
moduleName: function(filePath) {
return filePath.replace(/.js$/, '');
}
var transpiledLib = compileModules(lib, {
formatter: 'commonjs'
});
```
Transpiling to CommonJS:
### Transpiling to Bundle Format
The bundle format is perfect for packaging your app's modules into one file that
can be loaded in the browser _without_ needing a module loader.
```javascript
var transpileES6 = require('broccoli-es6-module-transpiler');
var compileModules = require('broccoli-es6-module-transpiler');
var transpiledLib = transpileES6(lib, {
type: 'cjs'
var transpiledLib = compileModules(lib, {
formatter: 'bundle',
output : 'app.js'
});
```
## Documentation
**Note:** The `output` option has a specified value to tell the transpiler where
to output the new JavaScript file that contains the bundled transpiled modules.
An `output` value is required when using the Bundle Format.
### `transpileES6(inputTree, options)`
### Transpiling to AMD
---
The latest version of Square's [transpiler][] is flexible and pluggable, and
while it doesn't ship with AMD support built-in you can use the AMD formatter:
[es6-module-transpiler-amd-formatter][amd-formatter].
`options.type` *{String}*
```javascript
var compileModules = require('broccoli-es6-module-transpiler');
var AMDFormatter = require('es6-module-transpiler-amd-formatter');
The type of module to transpile to.
var transpiledLib = compileModules(lib, {
formatter: new AMDFormatter()
});
```
Possible values: `amd`, `cjs`, `yui` or `globals`.
Default: `amd`.
## Documentation
### `compileModules(inputTree, [options])`
---
`options.moduleName` *{Function, String, `true`, null}*
`options.formatter` *{String | Object}*
The module name that is passed to the transpiler for each file.
The formatter instance or built-in name to use to transpile the modules.
Built-in formatters: `bundle`, `commonjs`.
- If `moduleName` is `null` an anonymous module will be generated.
- If `moduleName` is a string it will be passed directly the transpiler for all files.
- If `moduleName` is a function it will be called with the path of the current file as its sole argument. The return value of the function will be passed to the transpiler.
- If `moduleName` is `true` the filename will be used (after stripping the last three characters).
Default: `bundle`.
Default: `null`.
---
`options.transpilerOptions` *{Function, Object, null}*
`options.output` *{String}*
The options that are passed to the transpiler for each file.
The path where the transpiler should output the transpiled modules to. For
formatters that output one file per module, this should be a directory, while
formatters like the Bundle Format require a value for this option and it must be
a file path.
- If `transpilerOptions` is `null` no options will be passed.
- If `transpilerOptions` is an object it will be passed directly the transpiler for all files.
- If `transpilerOptions` is a function it will be called with the path of the current file as its sole argument. The return value of the function will be passed to the transpiler.
Default: `"."`.
Default: `null`.
[transpiler]: https://github.com/esnext/es6-module-transpiler
[prev-version]: https://github.com/mmun/broccoli-es6-module-transpiler/tree/transpiler-0.4
[amd-formatter]: https://github.com/caridy/es6-module-transpiler-amd-formatter

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc