├── .gitignore
├── .idea
├── codeStyles
│ └── codeStyleConfig.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── jsLibraryMappings.xml
├── misc.xml
├── modules.xml
├── node-webpackify.iml
├── typescript-compiler.xml
└── vcs.xml
├── .npmignore
├── LICENSE
├── README.md
├── dist
├── __tests__
│ ├── fixtures.js
│ └── fixtures.js.map
├── compiler.js
├── compiler.js.map
├── compiler.test.js
├── compiler.test.js.map
├── hook.js
├── hook.js.map
├── index.js
├── index.js.map
├── module-util.js
├── module-util.js.map
├── util-tests.js
├── util-tests.js.map
├── util-webpack.js
├── util-webpack.js.map
├── util.js
└── util.js.map
├── fixtures
├── basic
│ └── index.js
├── css
│ ├── file.css
│ ├── index.js
│ ├── register.js
│ └── webpack.config.js
├── postcss
│ ├── file.css
│ ├── file2.css
│ ├── index.js
│ ├── register.js
│ └── webpack.config.js
└── raw
│ ├── file.txt
│ ├── index.js
│ ├── register.js
│ └── webpack.config.js
├── index.js
├── package.json
├── src
├── __snapshots__
│ └── compiler.test.ts.snap
├── __tests__
│ ├── __snapshots__
│ │ └── fixtures.ts.snap
│ └── fixtures.ts
├── compiler.js
├── compiler.test.ts
├── hook.js
├── index.ts
├── module-util.js
├── util-tests.ts
├── util-webpack.ts
└── util.ts
├── tsconfig.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Node template
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 |
10 | # Runtime data
11 | pids
12 | *.pid
13 | *.seed
14 | *.pid.lock
15 |
16 | # Directory for instrumented libs generated by jscoverage/JSCover
17 | lib-cov
18 |
19 | # Coverage directory used by tools like istanbul
20 | coverage
21 |
22 | # nyc test coverage
23 | .nyc_output
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # Bower dependency directory (https://bower.io/)
29 | bower_components
30 |
31 | # node-waf configuration
32 | .lock-wscript
33 |
34 | # Compiled binary addons (https://nodejs.org/api/addons.html)
35 | build/Release
36 |
37 | # Dependency directories
38 | node_modules/
39 | jspm_packages/
40 |
41 | # TypeScript v1 declaration files
42 | typings/
43 |
44 | # Optional npm cache directory
45 | .npm
46 |
47 | # Optional eslint cache
48 | .eslintcache
49 |
50 | # Optional REPL history
51 | .node_repl_history
52 |
53 | # Output of 'npm pack'
54 | *.tgz
55 |
56 | # Yarn Integrity file
57 | .yarn-integrity
58 |
59 | # dotenv environment variables file
60 | .env
61 |
62 | # next.js build output
63 | .next
64 |
65 | /.cache
66 | /.idea/workspace.xml
67 | /preset
68 | /assets
69 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/node-webpackify.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/typescript-compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | /src
3 | /fixtures
4 | /preset
5 | /assets
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Bazyli Brzóska
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # node-webpackify
2 |
3 | Redirects all your Node `require()` calls to Webpack's module compiler,
4 | making it into a JIT (just-in-time) compiler.
5 |
6 | It can serve as a replacement for `babel-register` or `ts-node`.
7 |
8 | Based on the provided `webpack` config, `node-webpackify` will use:
9 | - `webpack`'s resolvers (including resolving of aliases, resolve plugins, etc.)
10 | - `webpack`'s rules (loaders)
11 |
12 | But NOT webpack's plugins (or at least that remains untested)!
13 | The reason is that `node-webpackify` will only run a handful of hooks required to setup the resolvers and loaders.
14 |
15 | Yes, this means you can use things like `css-loader` with Node or Electron.
16 | Think: ditching `karma-webpack` in place of `electron-mocha` for much faster testing.
17 |
18 | ## Usage
19 |
20 | `node-webpackify` exposes a `register` function, which you can use by calling it with the following arguments:
21 |
22 | ```js
23 | const webpackOptions = require('./webpack.config.js')
24 | require('node-webpackify')(
25 | // webpack options object:
26 | webpackOptions,
27 | // node-webpackify options object (optional):
28 | {
29 | // (optional) function(request: string, parentPath: string): boolean
30 | // can be used to limit which requests are run through the resolvers and loaders
31 | // when left undefined,
32 | //
33 | // @param request is the string passed into: require(request)
34 | // @param parentPath is the full, absolute path to the module that the request is located in
35 | test: (request: string, parentPath: string): boolean => true,
36 |
37 | testTransform: (filename: string, loaders: Array, request: string, parentFilename: string): boolean => true,
38 |
39 | // (optional) override webpack's target (default = 'node'), useful for Electron
40 | target,
41 | }
42 | )
43 | ```
44 |
45 | I'd recommend creating a `register-webpack.js` file with similar contents to the file above.
46 |
47 | Then, you can simply run your code by executing:
48 |
49 | ```bash
50 | node -r ./register-webpack src/entry
51 | ```
52 |
53 | ### Output code must be valid NodeJS code
54 |
55 | You need to ensure *none* of the output code contains ES6 `import`s (whether static or dynamic).
56 |
57 | If using Babel or TypeScript, ensure you set a CommonJS target for the module system.
58 |
59 | If you use dynamic `import()`s, you could add a babel plugin to transpile them into promisified `require()`s:
60 | - https://github.com/airbnb/babel-plugin-dynamic-import-node
61 |
62 | ## Why?
63 |
64 | - NodeJS-based testing without mocking non-JS files,
65 | e.g. running `jest` or `mocha` under Electron (which is Node + Chromium):
66 | - no build/rebuild step necessary
67 | - native watch mode
68 | - test your (post)CSS/SASS/CSSinJS *with* measuring and rendering, but *without* bundling
69 | - one config to rule them all: why should you need a different config for your testing platform,
70 | and a different one for your production?
71 | - run a Node REPL that uses your webpack configuration (resolvers, loaders, aliases),
72 | and behaves like webpack (supporting inline syntax like `require('!graphql-loader!./schema.graphql')`)
73 | - debug your `serverless` functions without `serverless-webpack`: no bundles, no sourcemap mess, no rebuilding!
74 | - things I didn't even think of 😄.
75 | - [Edit this README](https://github.com/niieani/node-webpackify/edit/master/README.md) if you have an interesting use-case!
76 |
77 | ## ES6 modules support
78 |
79 | `node-webpackify` does not add hooks to the ES6 modules system when the `--experimentalModules` flag is enabled.
80 |
81 | It shouldn't be too hard to add, as there are official APIs for hooking into that system.
82 | If you want to give it a go, send me a PR! :-)
83 |
84 | ## Performance
85 |
86 | We're transforming and loading each file on-demand, while all `require` calls are synchronous.
87 | Unfortunately this means any top-level `require`s will cascade down making the boot-up of your application slow.
88 |
89 | The way to solve this problem is to delay the `import`s as much as possible, which could be achieved using a babel plugin (explained below).
90 | It's likely not all codepaths in your application will be taken,
91 | meaning some files can be unnecessary, and others could be transformed and loaded just-in-time for their first use.
92 |
93 | This is really important in node, because `require` is synchronous, and cannot be parallelized.
94 | If you `require` any file and that contains top-level `require`s or static `import`s,
95 | all of those files, and all of *their* dependencies will have to be resolved and transformed before any other code is executed.
96 |
97 | If you're using `babel`, I recommend adding one of these plugins to the config passed into `node-webpackify` (it might not make sense in other cases):
98 | - https://github.com/zertosh/babel-plugin-transform-inline-imports-commonjs
99 | - https://github.com/princjef/babel-plugin-lazy-require
100 |
101 | They will make your `require`'s evaluate at the first moment they're used,
102 | rather than all upfront, making the start-up times much, much better.
103 |
104 | You could even try experimenting with transpiling the `node_modules` code with these, to get even better boot times!
105 |
106 | ### Open PRs with improvements!
107 |
108 | Since loaders can be slow, and `require`'s are synchronous, a lot could still be done to make `node-webpackify` faster:
109 | - long-term caching based on file timestamps (like `babel-register`)
110 | - improving logic for early bailing
111 | - resolve-only before creating the Webpack module
112 | - profile, find and eliminate bottlenecks!
113 |
114 | ## Debugging
115 |
116 | Lunch your app with a `DEBUG=node-webpackify:*` environment variable, e.g.:
117 |
118 | ```bash
119 | DEBUG=node-webpackify:* node -r ./register-webpack src/entry
120 | ```
121 |
122 | ## Using the compiler directly
123 |
124 | It might be useful for you to just use the extracted compiler,
125 | for example to write a `jest` transform plugin out of it.
126 |
127 | See the `src/compiler.test.ts` for details on usage.
128 |
--------------------------------------------------------------------------------
/dist/__tests__/fixtures.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const util_tests_1 = require("../util-tests");
4 | describe('uses a loader', () => {
5 | jest.setTimeout(10000);
6 | it('raw-loader', async () => {
7 | const result = await util_tests_1.runFixture('raw');
8 | expect(result.failed).toBe(false);
9 | expect(result.stdout).toMatchSnapshot();
10 | });
11 | it('css-loader and style-loader', async () => {
12 | const result = await util_tests_1.runFixture('css');
13 | expect(result.failed).toBe(false);
14 | expect(result.stdout).toMatchSnapshot();
15 | });
16 | it('postcss-loader', async () => {
17 | const result = await util_tests_1.runFixture('postcss');
18 | expect(result.failed).toBe(false);
19 | expect(result.stdout).toMatchSnapshot();
20 | });
21 | });
22 | //# sourceMappingURL=fixtures.js.map
--------------------------------------------------------------------------------
/dist/__tests__/fixtures.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/__tests__/fixtures.ts"],"names":[],"mappings":";;AAAA,8CAAwC;AAExC,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IAEtB,EAAE,CAAE,YAAY,EAAE,KAAK,IAAI,EAAE;QAC3B,MAAM,MAAM,GAAG,MAAM,uBAAU,CAAC,KAAK,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,EAAE,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAE,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,MAAM,GAAG,MAAM,uBAAU,CAAC,KAAK,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,EAAE,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAE,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,MAAM,GAAG,MAAM,uBAAU,CAAC,SAAS,CAAC,CAAA;QAC1C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,EAAE,CAAA;IACzC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
--------------------------------------------------------------------------------
/dist/compiler.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const tslib_1 = require("tslib");
4 | const webpack_1 = tslib_1.__importDefault(require("webpack/lib/webpack"));
5 | const fs_1 = tslib_1.__importDefault(require("fs"));
6 | const SingleEntryDependency_1 = tslib_1.__importDefault(require("webpack/lib/dependencies/SingleEntryDependency"));
7 | const SingleEntryPlugin_1 = tslib_1.__importDefault(require("webpack/lib/SingleEntryPlugin"));
8 | const util_1 = require("util");
9 | const util_webpack_1 = require("./util-webpack");
10 | const deasync = require('deasync');
11 | /** @typedef {import("webpack").Configuration} Configuration */
12 | /**
13 | * @typedef {{
14 | * compile: function(callback : function(Error, string) : void): void,
15 | * filename: string,
16 | * request: string,
17 | * needsTransforming: boolean,
18 | * loaders: Array,
19 | * }} SimpleCompiler
20 | */
21 | /**
22 | * @typedef {{
23 | * compile: function(): Promise,
24 | * filename: string,
25 | * request: string,
26 | * needsTransforming: boolean,
27 | * loaders: Array,
28 | * }} SimpleCompilerAsync
29 | */
30 | /**
31 | * @typedef {{
32 | * compile: function(): string,
33 | * filename: string,
34 | * request: string,
35 | * needsTransforming: boolean,
36 | * loaders: Array,
37 | * }} SimpleCompilerSync
38 | */
39 | /**
40 | * @param {Configuration} wpOptions
41 | * @param {function(Error, function(Error, SimpleCompiler=): void): void} callback
42 | * @returns {function(string, string, function(Error, SimpleCompiler=): void): void}
43 | */
44 | function getSimpleCompiler(wpOptions, callback) {
45 | const compiler = webpack_1.default(wpOptions || {});
46 | compiler.hooks.beforeRun.callAsync(compiler, (err) => {
47 | if (err)
48 | return callback(err);
49 | const params = compiler.newCompilationParams();
50 | compiler.hooks.beforeCompile.callAsync(params, (err) => {
51 | if (err)
52 | return callback(err);
53 | compiler.hooks.compile.call(params);
54 | const compilation = compiler.newCompilation(params);
55 | const moduleFactory = compilation.dependencyFactories.get(SingleEntryDependency_1.default);
56 | const { options, resolverFactory } = compiler;
57 | // we never need to parse:
58 | options.module.noParse = '';
59 | callback(undefined, (request, context, callback) => {
60 | moduleFactory.create({
61 | context,
62 | contextInfo: { issuer: '', compiler: 'webpack-node' },
63 | dependencies: [SingleEntryPlugin_1.default.createDependency(request, 'main')]
64 | }, (err, module) => {
65 | if (err)
66 | return callback(err);
67 | const resolver = resolverFactory.get('normal', module.resolveOptions);
68 | const compile = (callback) => {
69 | module.build(options, compilation, resolver, fs_1.default, () => {
70 | const { _source: sourceObject } = module;
71 | if (sourceObject != null)
72 | callback(null, sourceObject.source());
73 | else
74 | callback(new Error('No source returned'));
75 | });
76 | };
77 | const resourceAndQuery = module.request != null
78 | ? util_webpack_1.buildFilename(module.request)
79 | : [];
80 | const filename = resourceAndQuery && resourceAndQuery.join('?');
81 | const loaders = module.loaders || [];
82 | callback(null, {
83 | compile,
84 | module,
85 | request: module.request,
86 | loaders,
87 | resource: module.resource,
88 | filename,
89 | resourceAndQuery,
90 | needsTransforming: resourceAndQuery.length > 1 || loaders.length > 1,
91 | });
92 | });
93 | });
94 | });
95 | });
96 | }
97 | exports.getSimpleCompiler = getSimpleCompiler;
98 | const getSimpleCompilerAsyncBase = util_1.promisify(exports.getSimpleCompiler);
99 | const getSimpleCompilerSyncBase = deasync(exports.getSimpleCompiler);
100 | /**
101 | * @typedef {function(string, string): SimpleCompilerSync} GetModuleSync
102 | */
103 | /**
104 | * @type {function(Configuration): GetModuleSync}
105 | */
106 | exports.getSimpleCompilerSync = (wpOptions) => {
107 | const getModule = deasync(getSimpleCompilerSyncBase(wpOptions));
108 | /**
109 | * @param {string} request
110 | * @param {string} context
111 | * @returns {SimpleCompilerSync}
112 | */
113 | return function getModuleSync(request, context) {
114 | const _a = getModule(request, context), { compile } = _a, props = tslib_1.__rest(_a, ["compile"]);
115 | /** @type {SimpleCompilerSync} */
116 | return Object.assign({}, props, { compile: deasync(compile) });
117 | };
118 | };
119 | /**
120 | * @typedef {function(string, string): Promise} GetModuleAsync
121 | */
122 | /**
123 | * @type {function(Configuration): Promise}
124 | */
125 | exports.getSimpleCompilerAsync = async (wpOptions) => {
126 | const getModule = util_1.promisify(await getSimpleCompilerAsyncBase(wpOptions));
127 | /**
128 | * @param {string} request
129 | * @param {string} context
130 | * @returns {Promise}
131 | */
132 | return async function getModuleAsync(request, context) {
133 | const _a = await getModule(request, context), { compile } = _a, props = tslib_1.__rest(_a, ["compile"]);
134 | /** @type {SimpleCompilerAsync} */
135 | return Object.assign({}, props, { compile: util_1.promisify(compile) });
136 | };
137 | };
138 | //# sourceMappingURL=compiler.js.map
--------------------------------------------------------------------------------
/dist/compiler.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"compiler.js","sourceRoot":"","sources":["../src/compiler.js"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/dist/compiler.test.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const compiler_1 = require("./compiler");
4 | describe('simple compiler', () => {
5 | jest.setTimeout(10000);
6 | const wpOptions = {};
7 | test('compilation async', async () => {
8 | const getModule = await compiler_1.getSimpleCompilerAsync(wpOptions);
9 | const { compile } = await getModule('../fixtures/basic', __dirname);
10 | const source = await compile();
11 | expect(source).toMatchSnapshot();
12 | });
13 | test('compilation sync', () => {
14 | const getModule = compiler_1.getSimpleCompilerSync(wpOptions);
15 | const { compile } = getModule('../fixtures/basic', __dirname);
16 | const source = compile();
17 | expect(source).toMatchSnapshot();
18 | });
19 | });
20 | //# sourceMappingURL=compiler.test.js.map
--------------------------------------------------------------------------------
/dist/compiler.test.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"compiler.test.js","sourceRoot":"","sources":["../src/compiler.test.ts"],"names":[],"mappings":";;AAAA,yCAAwE;AAExE,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IAEtB,MAAM,SAAS,GAAG,EAAE,CAAA;IAEpB,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,SAAS,GAAG,MAAM,iCAAsB,CAAC,SAAS,CAAC,CAAA;QACzD,MAAM,EAAC,OAAO,EAAC,GAAG,MAAM,SAAS,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAA;QACjE,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;QAC9B,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,EAAE,CAAA;IAClC,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC5B,MAAM,SAAS,GAAG,gCAAqB,CAAC,SAAS,CAAC,CAAA;QAClD,MAAM,EAAC,OAAO,EAAC,GAAG,SAAS,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAA;QAC3D,MAAM,MAAM,GAAG,OAAO,EAAE,CAAA;QACxB,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,EAAE,CAAA;IAClC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
--------------------------------------------------------------------------------
/dist/hook.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const tslib_1 = require("tslib");
4 | // noinspection NpmUsedModulesInstalled
5 | const module_1 = tslib_1.__importDefault(require("module"));
6 | const path_1 = require("path");
7 | const compiler_1 = require("./compiler");
8 | const module_util_1 = require("./module-util");
9 | const util_1 = require("./util");
10 | const debug_1 = tslib_1.__importDefault(require("debug"));
11 | const { _load: load } = module_1.default;
12 | const logLoad = debug_1.default('webpack-node:load');
13 | const logResolve = debug_1.default('webpack-node:resolve');
14 | const logError = debug_1.default('webpack-node:error');
15 | const logCompilationStart = debug_1.default('webpack-node:compile:start');
16 | const logCompilationEnd = debug_1.default('webpack-node:compile:end');
17 | const anyLogEnabled = logLoad.enabled || logResolve.enabled || logError.enabled || logCompilationStart.enabled || logCompilationEnd.enabled;
18 | function register(wpOptions = {}, options = {}) {
19 | module_1.default._load = makeLoad(wpOptions, options);
20 | }
21 | exports.register = register;
22 | function makeLoad(wpOptions = {}, { test, testTransform, blacklistBuiltin = true, target = 'node', } = {}) {
23 | const getModule = compiler_1.getSimpleCompilerSync(Object.assign({}, wpOptions, { target }));
24 | return function _load(request, parentModule, isMain) {
25 | const { filename: parentFilename = '' } = parentModule || {};
26 | const shouldBail = isMain
27 | || parentFilename === ''
28 | || (blacklistBuiltin && module_1.default.builtinModules.some((builtIn) => request.startsWith(builtIn)))
29 | || (test && !test(request, parentFilename));
30 | if (!shouldBail) {
31 | try {
32 | const context = path_1.dirname(parentFilename);
33 | const prettyContext = anyLogEnabled ? util_1.getPrettyPath(context) : '';
34 | logLoad('loading %o', { request, context: prettyContext });
35 | const { compile, filename, needsTransforming, loaders } = getModule(request, context);
36 | const prettyFilename = anyLogEnabled ? util_1.getPrettyPath(filename) : '';
37 | logResolve('resolved %o', { filename: prettyFilename, needsTransforming });
38 | const wantsTransforming = testTransform
39 | && testTransform(filename, loaders, request, parentFilename, needsTransforming);
40 | if (wantsTransforming || needsTransforming) {
41 | const cachedModule = module_util_1.getCachedModule(filename, parentModule);
42 | if (cachedModule)
43 | return cachedModule.exports;
44 | logCompilationStart('compiling %s', prettyFilename);
45 | let compiled = '';
46 | try {
47 | compiled = compile();
48 | }
49 | catch (error) {
50 | logError('error transforming %o', { filename: prettyFilename, request });
51 | console.error(error);
52 | return {};
53 | }
54 | if (logCompilationEnd.enabled) {
55 | logCompilationEnd('compiled %O', {
56 | filename: prettyFilename,
57 | loaders: loaders.map(({ loader }) => util_1.getPrettyPath(loader)),
58 | });
59 | }
60 | try {
61 | const newModule = module_util_1.makeModule(filename, compiled, parentModule);
62 | return newModule.exports;
63 | }
64 | catch (error) {
65 | logError('error executing %o', { filename: prettyFilename, request });
66 | console.error(error);
67 | throw error;
68 | }
69 | }
70 | else {
71 | // we bailed, but we might already have resolved the filename - let's use it:
72 | request = filename != null ? filename : request;
73 | }
74 | }
75 | catch (err) {
76 | logError('error resolving %o', { request, parent: util_1.getPrettyPath(parentFilename), err });
77 | }
78 | }
79 | if (anyLogEnabled)
80 | logLoad('passing to native loader %s', util_1.getPrettyPath(request));
81 | return load(request, parentModule, isMain);
82 | };
83 | }
84 | exports.makeLoad = makeLoad;
85 | //# sourceMappingURL=hook.js.map
--------------------------------------------------------------------------------
/dist/hook.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"hook.js","sourceRoot":"","sources":["../src/hook.js"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | var hook_1 = require("./hook");
4 | exports.register = hook_1.register;
5 | //# sourceMappingURL=index.js.map
--------------------------------------------------------------------------------
/dist/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,+BAA+B;AAAvB,0BAAA,QAAQ,CAAA"}
--------------------------------------------------------------------------------
/dist/module-util.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const tslib_1 = require("tslib");
4 | // https://github.com/nodejs/node/blob/254058109f469f64b8ca23bb65a206abab380604/lib/internal/modules/cjs/loader.js#L87
5 | const module_1 = tslib_1.__importDefault(require("module"));
6 | const path_1 = require("path");
7 | function updateChildren(parent, child, scan) {
8 | const children = parent && parent.children;
9 | if (children && !(scan && children.includes(child)))
10 | children.push(child);
11 | }
12 | exports.updateChildren = updateChildren;
13 | exports.stripBom = (string /* : string */) => string.charCodeAt(0) === 0xFEFF ? string.slice(1) : string;
14 | // from https://github.com/nodejs/node/blob/254058109f469f64b8ca23bb65a206abab380604/lib/internal/modules/cjs/loader.js#L525
15 | function tryModuleLoad(newModule, filename, content) {
16 | let threw = true;
17 | try {
18 | // from https://github.com/nodejs/node/blob/254058109f469f64b8ca23bb65a206abab380604/lib/internal/modules/cjs/loader.js#L580
19 | newModule.filename = filename;
20 | newModule.paths = module_1.default._nodeModulePaths(path_1.dirname(filename));
21 | newModule._compile(exports.stripBom(content), filename);
22 | newModule.loaded = true;
23 | threw = false;
24 | }
25 | finally {
26 | if (threw) {
27 | delete module_1.default._cache[filename];
28 | }
29 | }
30 | }
31 | exports.tryModuleLoad = tryModuleLoad;
32 | exports.getCachedModule = (filename, parentModule) => {
33 | const cachedModule = module_1.default._cache[filename];
34 | if (cachedModule) {
35 | updateChildren(parentModule, cachedModule, true);
36 | return cachedModule;
37 | }
38 | return undefined;
39 | };
40 | function makeModule(filename, fileContents, parentModule) {
41 | const newModule = new module_1.default(filename, parentModule);
42 | module_1.default._cache[filename] = newModule;
43 | tryModuleLoad(newModule, filename, fileContents);
44 | return newModule;
45 | }
46 | exports.makeModule = makeModule;
47 | //# sourceMappingURL=module-util.js.map
--------------------------------------------------------------------------------
/dist/module-util.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"module-util.js","sourceRoot":"","sources":["../src/module-util.js"],"names":[],"mappings":";;;AAAA,sHAAsH;AACtH,4DAA2B;AAC3B,+BAA4B;AAE5B,SAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI;IAChD,MAAM,QAAQ,GAAG,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAA;IAC1C,IAAI,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC;AAJD,wCAIC;AAEY,QAAA,QAAQ,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,CAChD,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;AAE5D,4HAA4H;AAC5H,SAAgB,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO;IACxD,IAAI,KAAK,GAAG,IAAI,CAAA;IAChB,IAAI;QACF,4HAA4H;QAC5H,SAAS,CAAC,QAAQ,GAAG,QAAQ,CAAA;QAC7B,SAAS,CAAC,KAAK,GAAG,gBAAM,CAAC,gBAAgB,CAAC,cAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC5D,SAAS,CAAC,QAAQ,CAAC,gBAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAA;QAC/C,SAAS,CAAC,MAAM,GAAG,IAAI,CAAA;QACvB,KAAK,GAAG,KAAK,CAAA;KACd;YAAS;QACR,IAAI,KAAK,EAAE;YACT,OAAO,gBAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;SAC/B;KACF;AACH,CAAC;AAdD,sCAcC;AAEY,QAAA,eAAe,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE;IACxD,MAAM,YAAY,GAAG,gBAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC5C,IAAI,YAAY,EAAE;QAChB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,IAAI,CAAC,CAAA;QAChD,OAAO,YAAY,CAAA;KACpB;IACD,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED,SAAgB,UAAU,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY;IAC7D,MAAM,SAAS,GAAG,IAAI,gBAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IACpD,gBAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAA;IACnC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAA;IAChD,OAAO,SAAS,CAAA;AAClB,CAAC;AALD,gCAKC"}
--------------------------------------------------------------------------------
/dist/util-tests.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const tslib_1 = require("tslib");
4 | const path_1 = require("path");
5 | const execa_1 = tslib_1.__importDefault(require("execa"));
6 | function runFixture(name) {
7 | const fixturePath = path_1.resolve(__dirname, '..', 'fixtures', name);
8 | return execa_1.default('node', ['-r', path_1.join(fixturePath, 'register'), fixturePath]);
9 | }
10 | exports.runFixture = runFixture;
11 | //# sourceMappingURL=util-tests.js.map
--------------------------------------------------------------------------------
/dist/util-tests.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"util-tests.js","sourceRoot":"","sources":["../src/util-tests.ts"],"names":[],"mappings":";;;AAAA,+BAAkC;AAClC,0DAAyB;AAEzB,SAAgB,UAAU,CAAC,IAAY;IACrC,MAAM,WAAW,GAAG,cAAO,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA;IAC9D,OAAO,eAAK,CACV,MAAM,EACN,CAAC,IAAI,EAAE,WAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,WAAW,CAAC,CACnD,CAAA;AACH,CAAC;AAND,gCAMC"}
--------------------------------------------------------------------------------
/dist/util-webpack.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const tslib_1 = require("tslib");
4 | const crypto_1 = tslib_1.__importDefault(require("crypto"));
5 | /**
6 | * @param {string} request
7 | * @returns {[string, string]}
8 | */
9 | function buildFilename(request) {
10 | const loaders = request.split('!');
11 | const [resource, ...paramsParts] = loaders.pop().split('?');
12 | const hashFrom = `${loaders.join('!')}${paramsParts.join('?')}`;
13 | return hashFrom.length > 0
14 | ? [resource, crypto_1.default.createHash('md4').update(hashFrom).digest('hex')]
15 | : [resource];
16 | }
17 | exports.buildFilename = buildFilename;
18 | //# sourceMappingURL=util-webpack.js.map
--------------------------------------------------------------------------------
/dist/util-webpack.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"util-webpack.js","sourceRoot":"","sources":["../src/util-webpack.ts"],"names":[],"mappings":";;;AAAA,4DAA2B;AAE3B;;;GAGG;AACH,SAAgB,aAAa,CAAC,OAAe;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClC,MAAM,CAAC,QAAQ,EAAE,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,GAAG,EAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC5D,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IAC/D,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC;QACxB,CAAC,CAAC,CAAC,QAAQ,EAAE,gBAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;AAChB,CAAC;AAPD,sCAOC"}
--------------------------------------------------------------------------------
/dist/util.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const deasync = require("deasync");
4 | const util_1 = require("util");
5 | const path_1 = require("path");
6 | function deasyncAsyncFn(asyncFn) {
7 | return deasync(util_1.callbackify(asyncFn));
8 | }
9 | exports.deasyncAsyncFn = deasyncAsyncFn;
10 | exports.getPrettyPath = (filename) => filename
11 | .split(`${process.cwd()}${path_1.sep}`)
12 | .pop()
13 | .split(`node_modules${path_1.sep}`)
14 | .pop();
15 | //# sourceMappingURL=util.js.map
--------------------------------------------------------------------------------
/dist/util.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAAA,mCAAmC;AACnC,+BAAgC;AAChC,+BAAwB;AAYxB,SAAgB,cAAc,CAC5B,OAA6C;IAE7C,OAAO,OAAO,CAAC,kBAAW,CAAC,OAAO,CAAC,CAAC,CAAA;AACtC,CAAC;AAJD,wCAIC;AAEY,QAAA,aAAa,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,QAAQ;KACxD,KAAK,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,UAAG,EAAE,CAAC;KAC/B,GAAG,EAAG;KACN,KAAK,CAAC,eAAe,UAAG,EAAE,CAAC;KAC3B,GAAG,EAAG,CAAA"}
--------------------------------------------------------------------------------
/fixtures/basic/index.js:
--------------------------------------------------------------------------------
1 | console.log('basic')
2 |
--------------------------------------------------------------------------------
/fixtures/css/file.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: black;
3 | }
4 |
--------------------------------------------------------------------------------
/fixtures/css/index.js:
--------------------------------------------------------------------------------
1 | require('jsdom-global')()
2 | require('./file.css')
3 | console.log(document.documentElement.innerHTML)
4 |
--------------------------------------------------------------------------------
/fixtures/css/register.js:
--------------------------------------------------------------------------------
1 | require('../../dist/hook').register(require('./webpack.config'))
2 |
--------------------------------------------------------------------------------
/fixtures/css/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | module: {
3 | rules: [
4 | {
5 | test: /\.css$/,
6 | use: [
7 | { loader: 'style-loader' },
8 | { loader: 'css-loader' },
9 | ]
10 | }
11 | ],
12 | },
13 | }
--------------------------------------------------------------------------------
/fixtures/postcss/file.css:
--------------------------------------------------------------------------------
1 | @import "./file2.css";
2 |
3 | body {
4 | color: black;
5 | }
6 |
--------------------------------------------------------------------------------
/fixtures/postcss/file2.css:
--------------------------------------------------------------------------------
1 | .hello {
2 | color: blanchedalmond;
3 | animation: linear;
4 | }
--------------------------------------------------------------------------------
/fixtures/postcss/index.js:
--------------------------------------------------------------------------------
1 | require('jsdom-global')()
2 | require('./file.css')
3 | console.log(document.documentElement.innerHTML)
4 |
--------------------------------------------------------------------------------
/fixtures/postcss/register.js:
--------------------------------------------------------------------------------
1 | require('../../dist/hook').register(require('./webpack.config'))
2 |
--------------------------------------------------------------------------------
/fixtures/postcss/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | module: {
3 | rules: [
4 | {
5 | test: /\.css$/,
6 | use: [
7 | { loader: 'style-loader' },
8 | { loader: 'css-loader', options: { modules: true, importLoaders: 1 } },
9 | {
10 | loader: 'postcss-loader',
11 | options: {
12 | ident: 'postcss',
13 | plugins: (loader) => [
14 | require('postcss-import')({ root: loader.resourcePath }),
15 | require('autoprefixer')(),
16 | ]
17 | },
18 | },
19 | ]
20 | }
21 | ],
22 | },
23 | }
--------------------------------------------------------------------------------
/fixtures/raw/file.txt:
--------------------------------------------------------------------------------
1 | I'm a text file
--------------------------------------------------------------------------------
/fixtures/raw/index.js:
--------------------------------------------------------------------------------
1 | console.log(
2 | require('./file.txt')
3 | )
4 |
--------------------------------------------------------------------------------
/fixtures/raw/register.js:
--------------------------------------------------------------------------------
1 | require('../../dist/hook').register(require('./webpack.config'))
2 |
--------------------------------------------------------------------------------
/fixtures/raw/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | module: {
3 | rules: [
4 | {test: /\.txt$/, loader: 'raw-loader'}
5 | ],
6 | }
7 | }
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./dist/hook').register
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-webpackify",
3 | "version": "2.1.2",
4 | "description": "Utility for redirecting require() requests in Node to Webpack's module compiler",
5 | "keywords": [
6 | "node",
7 | "babel-register",
8 | "register",
9 | "JIT",
10 | "compiler",
11 | "webpack"
12 | ],
13 | "repository": {
14 | "type": "git",
15 | "url": "https://github.com/niieani/node-webpackify.git"
16 | },
17 | "homepage": "https://github.com/niieani/node-webpackify#readme",
18 | "author": "Bazyli Brzóska ",
19 | "collaborators": [
20 | "Bazyli Brzóska "
21 | ],
22 | "license": "MIT",
23 | "main": "index.js",
24 | "scripts": {
25 | "test": "jest",
26 | "build": "tsc -p ."
27 | },
28 | "dependencies": {
29 | "deasync": "^0.1.13",
30 | "debug": "^3.1.0",
31 | "tslib": "^1.9.0",
32 | "webpack": "^4.0.0"
33 | },
34 | "devDependencies": {
35 | "@types/deasync": "0.1.0",
36 | "@types/debug": "0.0.30",
37 | "@types/execa": "0.9.0",
38 | "@types/jest": "23.3.1",
39 | "@types/node": "^10.9.4",
40 | "@types/webpack": "4.4.11",
41 | "autoprefixer": "9.1.3",
42 | "css-loader": "1.0.0",
43 | "execa": "1.0.0",
44 | "jest": "23.5.0",
45 | "jsdom": "12.0.0",
46 | "jsdom-global": "3.0.2",
47 | "postcss-import": "12.0.0",
48 | "postcss-loader": "3.0.0",
49 | "raw-loader": "0.5.1",
50 | "style-loader": "0.23.0",
51 | "ts-jest": "23.1.4",
52 | "typescript": "3.0.3",
53 | "webpack-command": "0.4.1"
54 | },
55 | "jest": {
56 | "transform": {
57 | "^.+\\/src\\/.+\\.[jt]sx?$": "ts-jest"
58 | },
59 | "testRegex": "\\/src\\/.*(__tests__/.*|\\.test)\\.ts$",
60 | "moduleFileExtensions": [
61 | "ts",
62 | "tsx",
63 | "js",
64 | "jsx",
65 | "json",
66 | "node"
67 | ],
68 | "globals": {
69 | "ts-jest": {
70 | "skipBabel": true
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/__snapshots__/compiler.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`simple compiler compilation async 1`] = `
4 | "console.log('basic')
5 | "
6 | `;
7 |
8 | exports[`simple compiler compilation sync 1`] = `
9 | "console.log('basic')
10 | "
11 | `;
12 |
--------------------------------------------------------------------------------
/src/__tests__/__snapshots__/fixtures.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`uses a loader css-loader and style-loader 1`] = `
4 | " "
8 | `;
9 |
10 | exports[`uses a loader postcss-loader 1`] = `
11 | " "
21 | `;
22 |
23 | exports[`uses a loader raw-loader 1`] = `"I'm a text file"`;
24 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures.ts:
--------------------------------------------------------------------------------
1 | import {runFixture} from '../util-tests'
2 |
3 | describe('uses a loader', () => {
4 | jest.setTimeout(10000)
5 |
6 | it ('raw-loader', async () => {
7 | const result = await runFixture('raw')
8 | expect(result.failed).toBe(false)
9 | expect(result.stdout).toMatchSnapshot()
10 | })
11 |
12 | it ('css-loader and style-loader', async () => {
13 | const result = await runFixture('css')
14 | expect(result.failed).toBe(false)
15 | expect(result.stdout).toMatchSnapshot()
16 | })
17 |
18 | it ('postcss-loader', async () => {
19 | const result = await runFixture('postcss')
20 | expect(result.failed).toBe(false)
21 | expect(result.stdout).toMatchSnapshot()
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/src/compiler.js:
--------------------------------------------------------------------------------
1 | import webpack from 'webpack/lib/webpack'
2 | import fs from 'fs'
3 | import SingleEntryDependency from 'webpack/lib/dependencies/SingleEntryDependency'
4 | import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin'
5 | import {promisify} from 'util'
6 | import {buildFilename} from './util-webpack'
7 | const deasync = require('deasync')
8 |
9 | /** @typedef {import("webpack").Configuration} Configuration */
10 |
11 | /**
12 | * @typedef {{
13 | * compile: function(callback : function(Error, string) : void): void,
14 | * filename: string,
15 | * request: string,
16 | * needsTransforming: boolean,
17 | * loaders: Array,
18 | * }} SimpleCompiler
19 | */
20 |
21 | /**
22 | * @typedef {{
23 | * compile: function(): Promise,
24 | * filename: string,
25 | * request: string,
26 | * needsTransforming: boolean,
27 | * loaders: Array,
28 | * }} SimpleCompilerAsync
29 | */
30 |
31 | /**
32 | * @typedef {{
33 | * compile: function(): string,
34 | * filename: string,
35 | * request: string,
36 | * needsTransforming: boolean,
37 | * loaders: Array,
38 | * }} SimpleCompilerSync
39 | */
40 |
41 | /**
42 | * @param {Configuration} wpOptions
43 | * @param {function(Error, function(Error, SimpleCompiler=): void): void} callback
44 | * @returns {function(string, string, function(Error, SimpleCompiler=): void): void}
45 | */
46 | export function getSimpleCompiler(wpOptions, callback) {
47 | const compiler = webpack(wpOptions || {})
48 | compiler.hooks.beforeRun.callAsync(compiler, (err) => {
49 | if (err) return callback(err)
50 |
51 | const params = compiler.newCompilationParams()
52 | compiler.hooks.beforeCompile.callAsync(params, (err) => {
53 | if (err) return callback(err)
54 |
55 | compiler.hooks.compile.call(params)
56 | const compilation = compiler.newCompilation(params)
57 | const moduleFactory = compilation.dependencyFactories.get(SingleEntryDependency)
58 | const {options, resolverFactory} = compiler
59 |
60 | // we never need to parse:
61 | options.module.noParse = ''
62 |
63 | callback(undefined, (request, context, callback) => {
64 | moduleFactory.create({
65 | context,
66 | contextInfo: {issuer: '', compiler: 'webpack-node'},
67 | dependencies: [SingleEntryPlugin.createDependency(request, 'main')]
68 | }, (err, module) => {
69 | if (err) return callback(err)
70 |
71 | const resolver = resolverFactory.get('normal', module.resolveOptions)
72 | const compile = (callback) => {
73 | module.build(options, compilation, resolver, fs, () => {
74 | const {_source: sourceObject} = module
75 | if (sourceObject != null) callback(null, sourceObject.source())
76 | else callback(new Error('No source returned'))
77 | })
78 | }
79 |
80 | const resourceAndQuery = module.request != null
81 | ? buildFilename(module.request)
82 | : []
83 |
84 | const filename = resourceAndQuery && resourceAndQuery.join('?')
85 | const loaders = module.loaders || []
86 |
87 | callback(null, {
88 | compile,
89 | module,
90 | request: module.request,
91 | loaders,
92 | resource: module.resource,
93 | filename,
94 | resourceAndQuery,
95 | needsTransforming: resourceAndQuery.length > 1 || loaders.length > 1,
96 | })
97 | })
98 | })
99 | })
100 | })
101 | }
102 |
103 | const getSimpleCompilerAsyncBase = promisify(getSimpleCompiler)
104 | const getSimpleCompilerSyncBase = deasync(getSimpleCompiler)
105 |
106 | /**
107 | * @typedef {function(string, string): SimpleCompilerSync} GetModuleSync
108 | */
109 |
110 | /**
111 | * @type {function(Configuration): GetModuleSync}
112 | */
113 | export const getSimpleCompilerSync = (wpOptions) => {
114 | const getModule = deasync(getSimpleCompilerSyncBase(wpOptions))
115 | /**
116 | * @param {string} request
117 | * @param {string} context
118 | * @returns {SimpleCompilerSync}
119 | */
120 | return function getModuleSync(request, context) {
121 | const {compile, ...props} = getModule(request, context)
122 | /** @type {SimpleCompilerSync} */
123 | return {...props, compile: deasync(compile)}
124 | }
125 | }
126 |
127 | /**
128 | * @typedef {function(string, string): Promise} GetModuleAsync
129 | */
130 |
131 | /**
132 | * @type {function(Configuration): Promise}
133 | */
134 | export const getSimpleCompilerAsync = async (wpOptions) => {
135 | const getModule = promisify(await getSimpleCompilerAsyncBase(wpOptions))
136 | /**
137 | * @param {string} request
138 | * @param {string} context
139 | * @returns {Promise}
140 | */
141 | return async function getModuleAsync(request, context) {
142 | const {compile, ...props} = await getModule(request, context)
143 | /** @type {SimpleCompilerAsync} */
144 | return {...props, compile: promisify(compile)}
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/compiler.test.ts:
--------------------------------------------------------------------------------
1 | import {getSimpleCompilerAsync, getSimpleCompilerSync} from './compiler'
2 |
3 | describe('simple compiler', () => {
4 | jest.setTimeout(10000)
5 |
6 | const wpOptions = {}
7 |
8 | test('compilation async', async () => {
9 | const getModule = await getSimpleCompilerAsync(wpOptions)
10 | const {compile} = await getModule('../fixtures/basic', __dirname)
11 | const source = await compile()
12 | expect(source).toMatchSnapshot()
13 | })
14 |
15 | test('compilation sync', () => {
16 | const getModule = getSimpleCompilerSync(wpOptions)
17 | const {compile} = getModule('../fixtures/basic', __dirname)
18 | const source = compile()
19 | expect(source).toMatchSnapshot()
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/src/hook.js:
--------------------------------------------------------------------------------
1 | // noinspection NpmUsedModulesInstalled
2 | import Module from 'module'
3 | import {dirname, extname} from 'path'
4 | import {getSimpleCompilerSync} from './compiler'
5 | import {makeModule, getCachedModule} from './module-util'
6 | import {getPrettyPath} from './util'
7 | import makeDebug from 'debug'
8 | const {_load: load} = Module
9 |
10 | const logLoad = makeDebug('webpack-node:load')
11 | const logResolve = makeDebug('webpack-node:resolve')
12 | const logError = makeDebug('webpack-node:error')
13 | const logCompilationStart = makeDebug('webpack-node:compile:start')
14 | const logCompilationEnd = makeDebug('webpack-node:compile:end')
15 |
16 | const anyLogEnabled = logLoad.enabled || logResolve.enabled || logError.enabled || logCompilationStart.enabled || logCompilationEnd.enabled
17 |
18 | export function register(
19 | wpOptions = {},
20 | options = {},
21 | ) {
22 | Module._load = makeLoad(wpOptions, options)
23 | }
24 |
25 | export function makeLoad(
26 | wpOptions = {},
27 | {
28 | test,
29 | testTransform,
30 | blacklistBuiltin = true,
31 | target = 'node',
32 | } = {}
33 | ) {
34 | const getModule = getSimpleCompilerSync({...wpOptions, target})
35 |
36 | return function _load(request, parentModule, isMain) {
37 | const {filename: parentFilename = ''} = parentModule || {}
38 |
39 | const shouldBail = isMain
40 | || parentFilename === ''
41 | || (blacklistBuiltin && Module.builtinModules.some((builtIn) => request.startsWith(builtIn)))
42 | || (test && !test(request, parentFilename))
43 |
44 | if (!shouldBail) {
45 | try {
46 | const context = dirname(parentFilename)
47 | const prettyContext = anyLogEnabled ? getPrettyPath(context) : ''
48 | logLoad('loading %o', {request, context: prettyContext})
49 |
50 | const {compile, filename, needsTransforming, loaders} = getModule(request, context)
51 | const prettyFilename = anyLogEnabled ? getPrettyPath(filename) : ''
52 | logResolve('resolved %o', {filename: prettyFilename, needsTransforming})
53 |
54 | const wantsTransforming = testTransform
55 | && testTransform(filename, loaders, request, parentFilename, needsTransforming)
56 |
57 | if (wantsTransforming || needsTransforming) {
58 | const cachedModule = getCachedModule(filename, parentModule)
59 | if (cachedModule) return cachedModule.exports
60 |
61 | logCompilationStart('compiling %s', prettyFilename)
62 |
63 | let compiled = ''
64 | try {
65 | compiled = compile()
66 | } catch (error) {
67 | logError('error transforming %o', {filename: prettyFilename, request})
68 | console.error(error)
69 | return {}
70 | }
71 | if (logCompilationEnd.enabled) {
72 | logCompilationEnd('compiled %O', {
73 | filename: prettyFilename,
74 | loaders: loaders.map(({loader}) => getPrettyPath(loader)),
75 | })
76 | }
77 | try {
78 | const newModule = makeModule(filename, compiled, parentModule)
79 | return newModule.exports
80 | } catch (error) {
81 | logError('error executing %o', {filename: prettyFilename, request})
82 | console.error(error)
83 | throw error
84 | }
85 | } else {
86 | // we bailed, but we might already have resolved the filename - let's use it:
87 | request = filename != null ? filename : request
88 | }
89 | } catch (err) {
90 | logError('error resolving %o', {request, parent: getPrettyPath(parentFilename), err})
91 | }
92 | }
93 | if (anyLogEnabled) logLoad('passing to native loader %s', getPrettyPath(request))
94 | return load(request, parentModule, isMain)
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export {register} from './hook'
2 |
--------------------------------------------------------------------------------
/src/module-util.js:
--------------------------------------------------------------------------------
1 | // https://github.com/nodejs/node/blob/254058109f469f64b8ca23bb65a206abab380604/lib/internal/modules/cjs/loader.js#L87
2 | import Module from "module"
3 | import {dirname} from "path"
4 |
5 | export function updateChildren(parent, child, scan) {
6 | const children = parent && parent.children
7 | if (children && !(scan && children.includes(child)))
8 | children.push(child)
9 | }
10 |
11 | export const stripBom = (string /* : string */) =>
12 | string.charCodeAt(0) === 0xFEFF ? string.slice(1) : string
13 |
14 | // from https://github.com/nodejs/node/blob/254058109f469f64b8ca23bb65a206abab380604/lib/internal/modules/cjs/loader.js#L525
15 | export function tryModuleLoad(newModule, filename, content) {
16 | let threw = true
17 | try {
18 | // from https://github.com/nodejs/node/blob/254058109f469f64b8ca23bb65a206abab380604/lib/internal/modules/cjs/loader.js#L580
19 | newModule.filename = filename
20 | newModule.paths = Module._nodeModulePaths(dirname(filename))
21 | newModule._compile(stripBom(content), filename)
22 | newModule.loaded = true
23 | threw = false
24 | } finally {
25 | if (threw) {
26 | delete Module._cache[filename]
27 | }
28 | }
29 | }
30 |
31 | export const getCachedModule = (filename, parentModule) => {
32 | const cachedModule = Module._cache[filename]
33 | if (cachedModule) {
34 | updateChildren(parentModule, cachedModule, true)
35 | return cachedModule
36 | }
37 | return undefined
38 | }
39 |
40 | export function makeModule(filename, fileContents, parentModule) {
41 | const newModule = new Module(filename, parentModule)
42 | Module._cache[filename] = newModule
43 | tryModuleLoad(newModule, filename, fileContents)
44 | return newModule
45 | }
46 |
--------------------------------------------------------------------------------
/src/util-tests.ts:
--------------------------------------------------------------------------------
1 | import {resolve, join} from 'path'
2 | import execa from 'execa'
3 |
4 | export function runFixture(name: string) {
5 | const fixturePath = resolve(__dirname, '..', 'fixtures', name)
6 | return execa(
7 | 'node',
8 | ['-r', join(fixturePath, 'register'), fixturePath]
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/src/util-webpack.ts:
--------------------------------------------------------------------------------
1 | import crypto from 'crypto'
2 |
3 | /**
4 | * @param {string} request
5 | * @returns {[string, string]}
6 | */
7 | export function buildFilename(request: string) {
8 | const loaders = request.split('!')
9 | const [resource, ...paramsParts] = loaders.pop()!.split('?')
10 | const hashFrom = `${loaders.join('!')}${paramsParts.join('?')}`
11 | return hashFrom.length > 0
12 | ? [resource, crypto.createHash('md4').update(hashFrom).digest('hex')]
13 | : [resource]
14 | }
--------------------------------------------------------------------------------
/src/util.ts:
--------------------------------------------------------------------------------
1 | import deasync = require('deasync')
2 | import {callbackify} from 'util'
3 | import {sep} from 'path'
4 |
5 | type DeasyncAsyncFn = () => any>(
6 | asyncFn: (arg : T) => Promise
7 | ) => (arg: T) => U)
8 |
9 | export function deasyncAsyncFn(
10 | asyncFn: (arg : T) => Promise
11 | ): (arg: T) => U
12 | export function deasyncAsyncFn(
13 | asyncFn: (arg : T, arg2: T2) => Promise
14 | ): (arg: T, arg2: T2) => U
15 | export function deasyncAsyncFn(
16 | asyncFn: (...args : Array) => Promise
17 | ): (...args: Array) => U {
18 | return deasync(callbackify(asyncFn))
19 | }
20 |
21 | export const getPrettyPath = (filename: string) => filename
22 | .split(`${process.cwd()}${sep}`)
23 | .pop()!
24 | .split(`node_modules${sep}`)
25 | .pop()!
26 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | "target": "es2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
5 | "module": "commonjs", /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
6 | "lib": ["esnext"], /* Specify library files to be included in the compilation: */
7 | "allowJs": true, /* Allow javascript files to be compiled. */
8 | "checkJs": false, /* Report errors in .js files. */
9 | // "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
10 | // "jsxFactory": "console.log",
11 | // "declaration": true, /* Generates corresponding '.d.ts' file. */
12 | "sourceMap": true, /* Generates corresponding '.map' file. */
13 | // "outFile": "./", /* Concatenate and emit output to single file. */
14 | "outDir": "dist", /* Redirect output structure to the directory. */
15 | "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
16 | // "removeComments": true, /* Do not emit comments to output. */
17 | // "noEmit": true, /* Do not emit outputs. */
18 | "importHelpers": true, /* Import emit helpers from 'tslib'. */
19 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
20 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
21 |
22 | /* Strict Type-Checking Options */
23 | "strict": true, /* Enable all strict type-checking options. */
24 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
25 | // "strictNullChecks": true, /* Enable strict null checks. */
26 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
27 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
28 |
29 | /* Additional Checks */
30 | // "noUnusedLocals": true, /* Report errors on unused locals. */
31 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
32 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
33 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
34 |
35 | /* Module Resolution Options */
36 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
37 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
38 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
39 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
40 | // "typeRoots": [], /* List of folders to include type definitions from. */
41 | // "types": [], /* Type declaration files to be included in compilation. */
42 | "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
43 | "esModuleInterop": true,
44 | "watch": true
45 | /* Source Map Options */
46 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
47 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
48 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
49 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
50 |
51 | /* Experimental Options */
52 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
53 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
54 | // "skipLibCheck": true
55 | },
56 | "include": ["src"]
57 | }
58 |
--------------------------------------------------------------------------------