-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
src: add require transform pipeline #12349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -245,6 +245,55 @@ added: v0.3.0 | |
| Use the internal `require()` machinery to look up the location of a module, | ||
| but rather than loading the module, just return the resolved filename. | ||
|
|
||
| ### require.addTransform(transform) | ||
|
|
||
| * `transform` {Function} A function to use to transform module text given the | ||
| content and full path to the file. | ||
|
|
||
| Add a transform function to modify contents of a file loaded with `require()` | ||
| before passing it to the parser. This enables pre-compile transformations such | ||
| as transpiling code, replacing an interface with mock functions for testing or | ||
| instrumenting code for purposes such as gathering code coverage metrics or | ||
| tracing application behavior and measuring performance. | ||
|
|
||
| The `transform` function accepts the content string and full file path as the | ||
| first and second arguments. The function is expected to return a new content | ||
| string as the result of the transformation. | ||
|
|
||
| Multiple transforms may be added to the pipeline and will be applied in the | ||
| order they are added. | ||
|
|
||
|
|
||
| ```js | ||
| require.addTransform((content, filepath) => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| // Only apply the transform to a specific file | ||
| if (!/my\-module\.js$/.test(filename)) { | ||
| return content; | ||
| } | ||
| return ` | ||
| ${content} | ||
| const originalFunction = exports.someFunction; | ||
| exports.someFunction = function myMockedFunction(first, second, callback) { | ||
| var start = process.hrtime(); | ||
| function wrappedCallback() { | ||
| var end = process.hrtime(start); | ||
| console.log('execution time: %ds', end[0] + (end[1] / 1000000000)); | ||
| return callback(this, arguments); | ||
| } | ||
| return someFunction.call(null, first, second, wrappedCallback); | ||
| } | ||
| `; | ||
| }); | ||
| ``` | ||
|
|
||
| ### require.removeTransform(transform) | ||
|
|
||
| * `transform` {Function} A function previously given to `require.addTransform()` | ||
| which will be removed from the transform pipeline. | ||
|
|
||
| Removes a transform function from the transform pipeline so it will no longer | ||
| be applied to the contents of files loaded in future `require()` calls. | ||
|
|
||
| ## setImmediate(callback[, ...args]) | ||
| <!-- YAML | ||
| added: v0.9.1 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,39 @@ | ||
| 'use strict'; | ||
|
|
||
| const assert = require('assert'); | ||
|
|
||
| exports = module.exports = { | ||
| makeRequireFunction, | ||
| stripBOM, | ||
| addBuiltinLibsToObject | ||
| addBuiltinLibsToObject, | ||
| applyTransforms | ||
| }; | ||
|
|
||
| exports.requireDepth = 0; | ||
|
|
||
| const transforms = []; | ||
|
|
||
| function addTransform(transform) { | ||
| assert(typeof transform === 'function'); | ||
| transforms.push(transform); | ||
| } | ||
| function removeTransform(transform) { | ||
| const index = transforms.indexOf(transform); | ||
| if (index >= 0) { | ||
| transforms.splice(index, 1); | ||
| } | ||
| } | ||
|
|
||
| function applyTransforms(content, filename) { | ||
| return transforms.reduce((content, transform) => { | ||
| const next = transform(content, filename); | ||
| if (typeof next !== 'string') { | ||
| throw new Error('Module transforms must return the modified content'); | ||
|
||
| } | ||
| return next; | ||
| }, content); | ||
| } | ||
|
|
||
|
||
| // Invoke with makeRequireFunction(module) where |module| is the Module object | ||
| // to use as the context for the require() function. | ||
| function makeRequireFunction(mod) { | ||
|
|
@@ -27,6 +53,8 @@ function makeRequireFunction(mod) { | |
| } | ||
|
|
||
| require.resolve = resolve; | ||
| require.addTransform = addTransform; | ||
| require.removeTransform = removeTransform; | ||
|
|
||
| require.main = process.mainModule; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -537,6 +537,8 @@ var resolvedArgv; | |
| // the file. | ||
| // Returns exception, if any. | ||
| Module.prototype._compile = function(content, filename) { | ||
| content = internalModule.applyTransforms(content, filename); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder what the performance impact is here. |
||
|
|
||
| // Remove shebang | ||
| var contLen = content.length; | ||
| if (contLen >= 2) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| 'use strict'; | ||
|
|
||
| const common = require('../common'); | ||
| const assert = require('assert'); | ||
|
|
||
| // Juts so lint doesn't complain about unused common (which is required) | ||
| common.refreshTmpDir(); | ||
|
|
||
| function fooTransform(content, filename) { | ||
| if (!/test-require-transforms\.js$/.test(filename)) { | ||
| return content; | ||
| } | ||
| return 'module.exports = "foo"'; | ||
| } | ||
| function barTransform(content, filename) { | ||
| if (!/test-require-transforms\.js$/.test(filename)) { | ||
| return content; | ||
| } | ||
| return content.replace(/foo/, 'bar'); | ||
| } | ||
|
|
||
| // Test one-step transform | ||
| require.addTransform(fooTransform); | ||
| delete require.cache[require.resolve('./test-require-transforms')]; | ||
| const oneStep = require('./test-require-transforms'); | ||
| assert.strictEqual(oneStep, 'foo'); | ||
|
|
||
| // Test two-step transform | ||
| require.addTransform(barTransform); | ||
| delete require.cache[require.resolve('./test-require-transforms')]; | ||
| const twoStep = require('./test-require-transforms'); | ||
| assert.strictEqual(twoStep, 'bar'); | ||
|
|
||
| // Test transform step removal | ||
| require.removeTransform(barTransform); | ||
| delete require.cache[require.resolve('./test-require-transforms')]; | ||
| const removal = require('./test-require-transforms'); | ||
| assert.strictEqual(removal, 'foo'); |
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.
Type of
transformand the return type is missing.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 entire
.mdfile appears to be lacking argument and return type info, actually...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 added the
transformtype. It doesn't have a return value though.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.
Does this work on builtin modules?