├── .husky
├── pre-commit
└── commit-msg
├── .github
├── FUNDING.yml
├── CODEOWNERS
├── workflows
│ ├── dependency-review.yml
│ └── nodejs.yml
├── ISSUE_TEMPLATE
│ ├── SUPPORT.md
│ ├── FEATURE.md
│ ├── DOCS.md
│ ├── MODIFICATION.md
│ └── BUG.md
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── CONTRIBUTING.md
├── test
├── fixtures
│ ├── data.json
│ ├── error-export-null.js
│ ├── error-require.js
│ ├── executableFileEntry.js
│ ├── error-return-sync-wrong-obj.js
│ ├── error-call-sync.js
│ ├── error-return-async-wrong-obj.js
│ ├── error-return-sync-invalid-code.js
│ ├── babel.js
│ ├── cacheable.js
│ ├── error-return-async-invalid-code.js
│ ├── error-call-async.js
│ ├── code-es.js
│ ├── simple.js
│ ├── code-commonjs.js
│ ├── args.js
│ ├── buffer.js
│ ├── async-function.js
│ ├── promise.js
│ ├── executableFile.js
│ ├── executableFileES.mjs
│ ├── module-parent.js
│ ├── promise-compex.js
│ ├── dependencies.js
│ ├── error-emitted-with-dependencies.js
│ ├── dependencies-via-context.js
│ └── presets
│ │ ├── modernizr.js
│ │ └── figlet.js
├── helpers
│ ├── compile.js
│ ├── index.js
│ ├── readAsset.js
│ ├── execute.js
│ ├── normalizeErrors.js
│ ├── helperLoader.js
│ └── getCompiler.js
├── cjs.test.js
├── __snapshots__
│ ├── executableFile.test.js.snap
│ └── loader.test.js.snap
├── validate-options.test.js
├── executableFile.test.js
└── loader.test.js
├── .eslintignore
├── .prettierignore
├── .gitattributes
├── src
├── cjs.js
├── options.json
└── index.js
├── .eslintrc.js
├── jest.config.js
├── lint-staged.config.js
├── commitlint.config.js
├── .editorconfig
├── .gitignore
├── babel.config.js
├── .cspell.json
├── LICENSE
├── package.json
├── CHANGELOG.md
└── README.md
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | lint-staged
2 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | commitlint --edit $1
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | open_collective: webpack
2 |
--------------------------------------------------------------------------------
/test/fixtures/data.json:
--------------------------------------------------------------------------------
1 | {
2 | "years": "10"
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/error-export-null.js:
--------------------------------------------------------------------------------
1 | module.exports = null;
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | /coverage
2 | /dist
3 | /node_modules
4 | /test/fixtures
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | /coverage
2 | /dist
3 | /node_modules
4 | /test/fixtures
5 | CHANGELOG.md
--------------------------------------------------------------------------------
/test/fixtures/error-require.js:
--------------------------------------------------------------------------------
1 | throw new Error('This is a typical require() error');
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | yarn.lock -diff
2 | * text=auto
3 | bin/* eol=lf
4 | package-lock.json -diff
--------------------------------------------------------------------------------
/src/cjs.js:
--------------------------------------------------------------------------------
1 | const loader = require("./index");
2 |
3 | module.exports = loader.default;
4 |
--------------------------------------------------------------------------------
/test/fixtures/executableFileEntry.js:
--------------------------------------------------------------------------------
1 | const data = require('./data.json');
2 |
3 | module.exports = {data};
4 |
--------------------------------------------------------------------------------
/src/options.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Val Loader options",
3 | "type": "object",
4 | "additionalProperties": true
5 | }
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: ["@webpack-contrib/eslint-config-webpack", "prettier"],
4 | };
5 |
--------------------------------------------------------------------------------
/test/fixtures/error-return-sync-wrong-obj.js:
--------------------------------------------------------------------------------
1 | function errorReturnWrongObj() {
2 | return null;
3 | }
4 |
5 | module.exports = errorReturnWrongObj;
6 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | transformIgnorePatterns: [
3 | "/node_modules/",
4 | "\\.pnp\\.[^\\/]+$",
5 | "/test/fixtures/",
6 | ],
7 | };
8 |
--------------------------------------------------------------------------------
/test/fixtures/error-call-sync.js:
--------------------------------------------------------------------------------
1 | function errorCallSync() {
2 | throw new Error('Calling the function failed');
3 | }
4 |
5 | module.exports = errorCallSync;
6 |
--------------------------------------------------------------------------------
/lint-staged.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "*": ["prettier --write --ignore-unknown", "cspell --no-must-find-files"],
3 | "*.js": ["eslint --cache --fix"],
4 | };
5 |
--------------------------------------------------------------------------------
/test/fixtures/error-return-async-wrong-obj.js:
--------------------------------------------------------------------------------
1 | function errorReturnWrongObj() {
2 | return Promise.resolve(null);
3 | }
4 |
5 | module.exports = errorReturnWrongObj;
6 |
--------------------------------------------------------------------------------
/test/fixtures/error-return-sync-invalid-code.js:
--------------------------------------------------------------------------------
1 | function errorReturnInvalidCode() {
2 | return {
3 | code: null,
4 | };
5 | }
6 |
7 | module.exports = errorReturnInvalidCode;
8 |
--------------------------------------------------------------------------------
/test/fixtures/babel.js:
--------------------------------------------------------------------------------
1 | function babel() {
2 | return {
3 | code: 'module.exports = "hello world";',
4 | };
5 | }
6 |
7 | module.exports = {
8 | default: babel,
9 | };
10 |
--------------------------------------------------------------------------------
/test/fixtures/cacheable.js:
--------------------------------------------------------------------------------
1 | function cacheable() {
2 | return {
3 | cacheable: true,
4 | code: 'module.exports = "hello world";',
5 | };
6 | }
7 |
8 | module.exports = cacheable;
9 |
--------------------------------------------------------------------------------
/test/fixtures/error-return-async-invalid-code.js:
--------------------------------------------------------------------------------
1 | function errorReturnInvalidCode() {
2 | return Promise.resolve({
3 | code: null,
4 | });
5 | }
6 |
7 | module.exports = errorReturnInvalidCode;
8 |
--------------------------------------------------------------------------------
/test/fixtures/error-call-async.js:
--------------------------------------------------------------------------------
1 | function errorCallAsync() {
2 | return Promise.reject(
3 | new Error('Calling the function failed asynchronously')
4 | );
5 | }
6 |
7 | module.exports = errorCallAsync;
8 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ["@commitlint/config-conventional"],
3 | rules: {
4 | "header-max-length": [0],
5 | "body-max-line-length": [0],
6 | "footer-max-line-length": [0],
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # These are the default owners for everything in
2 | # webpack-contrib
3 | @webpack-contrib/org-maintainers
4 |
5 | # Add repository specific users / groups
6 | # below here for libs that are not maintained by the org.
7 |
--------------------------------------------------------------------------------
/test/fixtures/code-es.js:
--------------------------------------------------------------------------------
1 | function codeES() {
2 | return {
3 | code: 'export default "hello world";',
4 | sourceMap: { isASourceMap: true },
5 | ast: { isAnAst: true },
6 | };
7 | }
8 |
9 | module.exports = codeES;
10 |
--------------------------------------------------------------------------------
/test/fixtures/simple.js:
--------------------------------------------------------------------------------
1 | function simple() {
2 | return {
3 | code: 'module.exports = "hello world";',
4 | sourceMap: { isASourceMap: true },
5 | ast: { isAnAst: true },
6 | };
7 | }
8 |
9 | module.exports = simple;
10 |
--------------------------------------------------------------------------------
/test/fixtures/code-commonjs.js:
--------------------------------------------------------------------------------
1 | function codeES() {
2 | return {
3 | code: 'module.exports = "hello world";',
4 | sourceMap: { isASourceMap: true },
5 | ast: { isAnAst: true },
6 | };
7 | }
8 |
9 | module.exports = codeES;
10 |
--------------------------------------------------------------------------------
/test/fixtures/args.js:
--------------------------------------------------------------------------------
1 | function args(options) {
2 | return {
3 | code: 'module.exports = "hello world";',
4 | // We use the ast property because it is not validated
5 | ast: [options],
6 | };
7 | }
8 |
9 | module.exports = args;
10 |
--------------------------------------------------------------------------------
/test/fixtures/buffer.js:
--------------------------------------------------------------------------------
1 | function buffer() {
2 | return {
3 | code: Buffer.from('module.exports = "hello world";'),
4 | sourceMap: { isASourceMap: true },
5 | ast: { isAnAst: true },
6 | };
7 | }
8 |
9 | module.exports = buffer;
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/test/fixtures/async-function.js:
--------------------------------------------------------------------------------
1 | async function simple() {
2 | return {
3 | code: 'module.exports = "hello world";',
4 | sourceMap: { isASourceMap: true },
5 | ast: { isAnAst: true },
6 | };
7 | }
8 |
9 | module.exports = simple;
10 |
--------------------------------------------------------------------------------
/test/helpers/compile.js:
--------------------------------------------------------------------------------
1 | export default (compiler) =>
2 | new Promise((resolve, reject) => {
3 | compiler.run((error, stats) => {
4 | if (error) {
5 | return reject(error);
6 | }
7 |
8 | return resolve(stats);
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/test/fixtures/promise.js:
--------------------------------------------------------------------------------
1 | function promise() {
2 | return Promise.resolve({
3 | cacheable: true,
4 | code: 'module.exports = "hello world";',
5 | sourceMap: { isASourceMap: true },
6 | ast: { isAnAst: true },
7 | });
8 | }
9 |
10 | module.exports = promise;
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | Thumbs.db
3 |
4 | .idea
5 | .vscode
6 | .eslintcache
7 | *.sublime-project
8 | *.sublime-workspace
9 |
10 | /dist
11 | /local
12 | /reports
13 | /coverage
14 | /node_modules
15 | /test/output
16 |
17 | logs
18 | *.log
19 | npm-debug.log*
20 | yarn-debug.log*
21 | *.iml
22 |
--------------------------------------------------------------------------------
/test/fixtures/executableFile.js:
--------------------------------------------------------------------------------
1 | module.exports = function yearsInMs(options, loaderContext, content) {
2 | const {years} = JSON.parse(content);
3 | const value = years * 365 * 24 * 60 * 60 * 1000;
4 |
5 | return {
6 | cacheable: true,
7 | code: "module.exports = " + value,
8 | };
9 | };
10 |
--------------------------------------------------------------------------------
/test/fixtures/executableFileES.mjs:
--------------------------------------------------------------------------------
1 | export default function yearsInMs(options, loaderContext, content) {
2 | const {years} = JSON.parse(content);
3 | const value = years * 365 * 24 * 60 * 60 * 1000;
4 |
5 | return {
6 | cacheable: true,
7 | code: "export default " + value,
8 | };
9 | };
10 |
--------------------------------------------------------------------------------
/test/fixtures/module-parent.js:
--------------------------------------------------------------------------------
1 | function simple() {
2 | return {
3 | code: 'module.exports = "hello world";',
4 | sourceMap: { isASourceMap: true },
5 | ast: {
6 | isAnAst: true,
7 | hasParent: Boolean(module.parent)
8 | },
9 | };
10 | }
11 |
12 | module.exports = simple;
13 |
--------------------------------------------------------------------------------
/test/cjs.test.js:
--------------------------------------------------------------------------------
1 | import src from "../src";
2 | import cjs from "../src/cjs";
3 |
4 | describe("CJS", () => {
5 | it("should export loader", () => {
6 | expect(cjs).toEqual(src);
7 | });
8 |
9 | it('should export "raw" flag', () => {
10 | expect(cjs.raw).toBeUndefined();
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/test/fixtures/promise-compex.js:
--------------------------------------------------------------------------------
1 | function promise() {
2 | return new Promise((resolve) => {
3 | setTimeout(() => {
4 | resolve({
5 | code: 'module.exports = "hello world";',
6 | sourceMap: { isASourceMap: true },
7 | ast: { isAnAst: true },
8 | })
9 | }, 100)
10 | });
11 | }
12 |
13 | module.exports = promise;
14 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | const MIN_BABEL_VERSION = 7;
2 |
3 | module.exports = (api) => {
4 | api.assertVersion(MIN_BABEL_VERSION);
5 | api.cache(true);
6 |
7 | return {
8 | presets: [
9 | [
10 | "@babel/preset-env",
11 | {
12 | targets: {
13 | node: "18.12.0",
14 | },
15 | },
16 | ],
17 | ],
18 | };
19 | };
20 |
--------------------------------------------------------------------------------
/.github/workflows/dependency-review.yml:
--------------------------------------------------------------------------------
1 | name: "Dependency Review"
2 | on: [pull_request]
3 |
4 | permissions:
5 | contents: read
6 |
7 | jobs:
8 | dependency-review:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: "Checkout Repository"
12 | uses: actions/checkout@v4
13 | - name: "Dependency Review"
14 | uses: actions/dependency-review-action@v4
15 |
--------------------------------------------------------------------------------
/test/helpers/index.js:
--------------------------------------------------------------------------------
1 | import compile from "./compile";
2 | import execute from "./execute";
3 | import getCompiler from "./getCompiler";
4 | import helperLoader from "./helperLoader";
5 | import normalizeErrors from "./normalizeErrors";
6 | import readAsset from "./readAsset";
7 |
8 | export {
9 | compile,
10 | execute,
11 | getCompiler,
12 | helperLoader,
13 | normalizeErrors,
14 | readAsset,
15 | };
16 |
--------------------------------------------------------------------------------
/test/helpers/readAsset.js:
--------------------------------------------------------------------------------
1 | import path from "path";
2 |
3 | export default (asset, compiler, stats) => {
4 | const usedFs = compiler.outputFileSystem;
5 | const outputPath = stats.compilation.outputOptions.path;
6 | let data = "";
7 |
8 | try {
9 | data = usedFs.readFileSync(path.join(outputPath, asset)).toString();
10 | } catch (error) {
11 | data = error.toString();
12 | }
13 |
14 | return data;
15 | };
16 |
--------------------------------------------------------------------------------
/test/fixtures/dependencies.js:
--------------------------------------------------------------------------------
1 | function dependencies() {
2 | return {
3 | dependencies: [
4 | require.resolve('./args.js'),
5 | require.resolve('./simple.js'),
6 | ],
7 | buildDependencies: [
8 | require.resolve('./args.js'),
9 | require.resolve('./simple.js'),
10 | ],
11 | contextDependencies: [__dirname],
12 | code: 'module.exports = "hello world";',
13 | };
14 | }
15 |
16 | module.exports = dependencies;
17 |
--------------------------------------------------------------------------------
/test/fixtures/error-emitted-with-dependencies.js:
--------------------------------------------------------------------------------
1 | function errorEmittedWithDependencies(options, loaderOptions) {
2 | loaderOptions.emitError(new Error('Calling the function failed'));
3 |
4 | return {
5 | dependencies: [
6 | require.resolve('./args.js'),
7 | require.resolve('./simple.js'),
8 | ],
9 | contextDependencies: [__dirname],
10 | code: 'module.exports = "hello world";',
11 | };
12 | }
13 |
14 | module.exports = errorEmittedWithDependencies;
15 |
--------------------------------------------------------------------------------
/.cspell.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2",
3 | "language": "en,en-gb",
4 | "words": [
5 | "serviceworker",
6 | "flexbox",
7 | "modernizr",
8 | "compex",
9 | "memfs",
10 | "Modernizr",
11 | "serviceworker",
12 | "commitlint",
13 | "modenizr"
14 | ],
15 |
16 | "ignorePaths": [
17 | "CHANGELOG.md",
18 | "package.json",
19 | "dist/**",
20 | "**/__snapshots__/**",
21 | "package-lock.json",
22 | "node_modules",
23 | "coverage",
24 | "*.log"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/SUPPORT.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🆘 Support, Help, and Advice
3 | about: 👉🏽 Need support, help, or advice? Don't open an issue - visit "GitHub Discussions" or "Stack Overflow" instead.
4 | ---
5 |
6 | Hey there! 👋
7 |
8 | If you need support, help, or advice then this is not the right place to ask.
9 |
10 | Please visit one of the following instead:
11 |
12 | - [GitHub Discussions](https://github.com/webpack/webpack/discussions)
13 | - [Stack Overflow](https://stackoverflow.com/questions/tagged/webpack)
14 |
15 | Thanks for understanding!
16 |
--------------------------------------------------------------------------------
/test/fixtures/dependencies-via-context.js:
--------------------------------------------------------------------------------
1 | function dependencies(options, loaderContext) {
2 | loaderContext.addDependency(require.resolve('./args.js'));
3 | loaderContext.addDependency(require.resolve('./simple.js'));
4 | loaderContext.addBuildDependency(require.resolve('./args.js'));
5 | loaderContext.addBuildDependency(require.resolve('./simple.js'));
6 | loaderContext.addBuildDependency(__dirname);
7 | loaderContext.addContextDependency(__dirname);
8 |
9 | return {
10 | code: 'module.exports = "hello world";',
11 | };
12 | }
13 |
14 | module.exports = dependencies;
15 |
--------------------------------------------------------------------------------
/test/fixtures/presets/modernizr.js:
--------------------------------------------------------------------------------
1 | const modernizr = require("modernizr");
2 |
3 | module.exports = function(options) {
4 | return new Promise(function(resolve) {
5 | // It is impossible to throw an error because modernizr causes the process.exit(1)
6 | modernizr.build(options, function(output) {
7 | resolve({
8 | cacheable: true,
9 | code: `var modernizr; var hadGlobal = 'Modernizr' in window; var oldGlobal = window.Modernizr; ${output} modernizr = window.Modernizr; if (hadGlobal) { window.Modernizr = oldGlobal; } else { delete window.Modernizr; } export default modernizr;`
10 | });
11 | });
12 | });
13 | };
14 |
--------------------------------------------------------------------------------
/test/helpers/execute.js:
--------------------------------------------------------------------------------
1 | import Module from "module";
2 | import path from "path";
3 |
4 | const parentModule = module;
5 |
6 | export default (code) => {
7 | const resource = "test.js";
8 | const module = new Module(resource, parentModule);
9 | // eslint-disable-next-line no-underscore-dangle
10 | module.paths = Module._nodeModulePaths(
11 | path.resolve(__dirname, "../fixtures"),
12 | );
13 | module.filename = resource;
14 |
15 | // eslint-disable-next-line no-underscore-dangle
16 | module._compile(
17 | `let __export__;${code};module.exports = __export__;`,
18 | resource,
19 | );
20 |
21 | return module.exports;
22 | };
23 |
--------------------------------------------------------------------------------
/test/helpers/normalizeErrors.js:
--------------------------------------------------------------------------------
1 | function removeCWD(str) {
2 | const isWin = process.platform === "win32";
3 | let cwd = process.cwd();
4 |
5 | if (isWin) {
6 | // eslint-disable-next-line no-param-reassign
7 | str = str.replace(/\\/g, "/");
8 | // eslint-disable-next-line no-param-reassign
9 | cwd = cwd.replace(/\\/g, "/");
10 | }
11 |
12 | return str
13 | .replace(/\(from .*?\)/, "(from `replaced original path`)")
14 | .replace(new RegExp(cwd, "g"), "")
15 | .replace(
16 | /Cannot read property 'get' of undefined/,
17 | "Cannot read properties of undefined (reading 'get')",
18 | );
19 | }
20 |
21 | export default (errors) =>
22 | errors.map((error) =>
23 | removeCWD(error.toString().split("\n").slice(0, 2).join("\n")),
24 | );
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/FEATURE.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: ✨ Feature Request
3 | about: Suggest an idea for this project
4 | ---
5 |
6 |
7 |
8 |
9 | ### Feature Proposal
10 |
11 |
12 |
13 |
14 |
15 |
16 | ### Feature Use Case
17 |
18 |
19 |
20 | ### Please paste the results of `npx webpack-cli info` here, and mention other relevant information.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/DOCS.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 📚 Documentation
3 | about: Are the docs lacking or missing something? Do they need some new 🔥 hotness? Tell us here.
4 | ---
5 |
6 |
7 |
8 |
9 | Documentation is:
10 |
11 |
12 |
13 | - [ ] Missing
14 | - [ ] Needed
15 | - [ ] Confusing
16 | - [ ] Not Sure?
17 |
18 | ### Please Explain in Detail...
19 |
20 |
21 |
22 |
23 |
24 |
25 | ### Your Proposal for Changes
26 |
--------------------------------------------------------------------------------
/test/__snapshots__/executableFile.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`executableFile option should emit error: errors 1`] = `
4 | [
5 | "ModuleBuildError: Module build failed (from \`replaced original path\`):
6 | Error: Unable to require "/test/fixtures/error-require.js": Error: This is a typical require() error",
7 | ]
8 | `;
9 |
10 | exports[`executableFile option should emit error: warnings 1`] = `[]`;
11 |
12 | exports[`executableFile option should work with commonjs format: errors 1`] = `[]`;
13 |
14 | exports[`executableFile option should work with commonjs format: result 1`] = `
15 | "{
16 | "content": "module.exports = 315360000000",
17 | "map": null,
18 | "meta": null,
19 | "dependencies": [
20 | "test/fixtures/data.json"
21 | ],
22 | "contextDependencies": [],
23 | "buildDependencies": []
24 | }"
25 | `;
26 |
27 | exports[`executableFile option should work with commonjs format: warnings 1`] = `[]`;
28 |
--------------------------------------------------------------------------------
/test/helpers/helperLoader.js:
--------------------------------------------------------------------------------
1 | import path from "path";
2 |
3 | function rel(p) {
4 | return path.relative(process.cwd(), p);
5 | }
6 |
7 | export default function helperLoader(content, map, meta) {
8 | const dependencies = this.getDependencies().map((dependency) =>
9 | rel(dependency).replace(/\\/g, "/"),
10 | );
11 | const contextDependencies = this.getContextDependencies().map((dependency) =>
12 | rel(dependency).replace(/\\/g, "/"),
13 | );
14 |
15 | const buildDependencies = Array.from(
16 | this._module.buildInfo.buildDependencies || [],
17 | ).map((dependency) => rel(dependency).replace(/\\/g, "/"));
18 | const json = JSON.stringify(
19 | {
20 | content,
21 | map,
22 | meta,
23 | dependencies,
24 | contextDependencies,
25 | buildDependencies,
26 | },
27 | null,
28 | " ",
29 | )
30 | .replace(/\u2028/g, "\\u2028")
31 | .replace(/\u2029/g, "\\u2029");
32 |
33 | this.emitFile("val-loader.js", json, false);
34 |
35 | return ``;
36 | }
37 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
10 |
11 | This PR contains a:
12 |
13 | - [ ] **bugfix**
14 | - [ ] new **feature**
15 | - [ ] **code refactor**
16 | - [ ] **test update**
17 | - [ ] **typo fix**
18 | - [ ] **metadata update**
19 |
20 | ### Motivation / Use-Case
21 |
22 |
27 |
28 | ### Breaking Changes
29 |
30 |
34 |
35 | ### Additional Info
36 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/MODIFICATION.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🔧 Modification Request
3 | about: Want something to work differently? Have an alternative approach? This is the template for you.
4 | ---
5 |
6 |
7 |
8 |
9 | ### Modification Proposal
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ### Expected Behavior / Situation
18 |
19 |
20 |
21 | ### Actual Behavior / Situation
22 |
23 |
24 |
25 | ### Please paste the results of `npx webpack-cli info` here, and mention other relevant information.
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright JS Foundation and other contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | 'Software'), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/test/helpers/getCompiler.js:
--------------------------------------------------------------------------------
1 | import path from "path";
2 |
3 | import webpack from "webpack";
4 | import { createFsFromVolume, Volume } from "memfs";
5 |
6 | export default (fixture, loaderOptions = {}, config = {}) => {
7 | const fullConfig = {
8 | mode: "development",
9 | devtool: config.devtool || false,
10 | context: path.resolve(__dirname, "../fixtures"),
11 | entry: path.resolve(__dirname, "../fixtures", fixture),
12 | output: {
13 | path: path.resolve(__dirname, "../outputs/"),
14 | filename: "[name].bundle.js",
15 | },
16 | module: {
17 | rules: [
18 | {
19 | test: /\.js$/i,
20 | rules: [
21 | {
22 | loader: require.resolve("./helperLoader.js"),
23 | },
24 | {
25 | loader: require.resolve("../../src"),
26 | options: loaderOptions,
27 | },
28 | ],
29 | },
30 | ],
31 | },
32 | plugins: [],
33 | ...config,
34 | };
35 |
36 | const compiler = webpack(fullConfig);
37 |
38 | if (!config.outputFileSystem) {
39 | compiler.outputFileSystem = createFsFromVolume(new Volume());
40 | }
41 |
42 | return compiler;
43 | };
44 |
--------------------------------------------------------------------------------
/test/fixtures/presets/figlet.js:
--------------------------------------------------------------------------------
1 | const figlet = require("figlet");
2 |
3 | function wrapOutput(output, config) {
4 | let figletOutput = "";
5 |
6 | if (config.textBefore) {
7 | figletOutput += encodeURI(`${config.textBefore}\n`);
8 | }
9 |
10 | output.split("\n").forEach(line => {
11 | figletOutput += encodeURI(`${line}\n`);
12 | });
13 |
14 | if (config.textAfter) {
15 | figletOutput += encodeURI(`${config.textAfter}\n`);
16 | }
17 |
18 | return `module.exports = decodeURI("${figletOutput}");`;
19 | }
20 |
21 | module.exports = function (options) {
22 | const defaultConfig = {
23 | fontOptions: {
24 | font: "ANSI Shadow",
25 | horizontalLayout: "default",
26 | kerning: "default",
27 | verticalLayout: "default"
28 | },
29 | text: "FIGLET-LOADER",
30 | textAfter: null,
31 | textBefore: null
32 | };
33 |
34 | const config = Object.assign({}, defaultConfig, options);
35 |
36 | return new Promise(function(resolve, reject) {
37 | figlet.text(config.text, config.fontOptions, (error, output) => {
38 | if (error) {
39 | return reject(error)
40 | }
41 |
42 | resolve({
43 | code: 'module.exports = ' + wrapOutput(output, config)
44 | });
45 | });
46 | });
47 | }
48 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/BUG.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🐛 Bug Report
3 | about: Something went awry and you'd like to tell us about it.
4 | ---
5 |
6 |
7 |
8 |
9 | ### Bug report
10 |
11 |
12 |
13 |
14 |
15 |
16 | ### Actual Behavior
17 |
18 |
19 |
20 | ### Expected Behavior
21 |
22 |
23 |
24 |
25 | ### How Do We Reproduce?
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ### Please paste the results of `npx webpack-cli info` here, and mention other relevant information.
34 |
--------------------------------------------------------------------------------
/test/validate-options.test.js:
--------------------------------------------------------------------------------
1 | import { getCompiler, compile } from "./helpers";
2 |
3 | describe("validate options", () => {
4 | const tests = {
5 | unknown: {
6 | success: [1, true, false, "test", /test/, [], {}, { foo: "bar" }],
7 | failure: [],
8 | },
9 | };
10 |
11 | function stringifyValue(value) {
12 | if (
13 | Array.isArray(value) ||
14 | (value && typeof value === "object" && value.constructor === Object)
15 | ) {
16 | return JSON.stringify(value);
17 | }
18 |
19 | return value;
20 | }
21 |
22 | async function createTestCase(key, value, type) {
23 | it(`should ${
24 | type === "success" ? "successfully validate" : "throw an error on"
25 | } the "${key}" option with "${stringifyValue(value)}" value`, async () => {
26 | const compiler = getCompiler("simple.js", { [key]: value });
27 |
28 | let stats;
29 |
30 | try {
31 | stats = await compile(compiler);
32 | } finally {
33 | if (type === "success") {
34 | expect(stats.hasErrors()).toBe(false);
35 | } else if (type === "failure") {
36 | const {
37 | compilation: { errors },
38 | } = stats;
39 |
40 | expect(errors).toHaveLength(1);
41 | expect(() => {
42 | throw new Error(errors[0].error.message);
43 | }).toThrowErrorMatchingSnapshot();
44 | }
45 | }
46 | });
47 | }
48 |
49 | for (const [key, values] of Object.entries(tests)) {
50 | for (const type of Object.keys(values)) {
51 | for (const value of values[type]) {
52 | createTestCase(key, value, type);
53 | }
54 | }
55 | }
56 | });
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "val-loader",
3 | "version": "6.0.0",
4 | "description": "val loader module for webpack",
5 | "license": "MIT",
6 | "repository": "webpack-contrib/val-loader",
7 | "author": "Tobias Koppers @sokra",
8 | "homepage": "https://github.com/webpack-contrib/val-loader",
9 | "bugs": "https://github.com/webpack-contrib/val-loader/issues",
10 | "funding": {
11 | "type": "opencollective",
12 | "url": "https://opencollective.com/webpack"
13 | },
14 | "main": "dist/cjs.js",
15 | "engines": {
16 | "node": ">= 18.12.0"
17 | },
18 | "scripts": {
19 | "start": "npm run build -- -w",
20 | "clean": "del-cli dist",
21 | "prebuild": "npm run clean",
22 | "build": "cross-env NODE_ENV=production babel src -d dist --copy-files",
23 | "commitlint": "commitlint --from=master",
24 | "security": "npm audit --production",
25 | "lint:prettier": "prettier --list-different .",
26 | "lint:js": "eslint --cache .",
27 | "lint:spelling": "cspell --no-must-find-files --cache --quiet \"**/*.*\"",
28 | "lint": "npm-run-all -l -p \"lint:**\"",
29 | "fix:js": "npm run lint:js -- --fix",
30 | "fix:prettier": "npm run lint:prettier -- --write",
31 | "fix": "npm-run-all -l fix:js fix:prettier",
32 | "test:only": "cross-env NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest",
33 | "test:watch": "npm run test:only -- --watch",
34 | "test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
35 | "pretest": "npm run lint",
36 | "test": "npm run test:coverage",
37 | "prepare": "husky && npm run build",
38 | "release": "standard-version"
39 | },
40 | "files": [
41 | "dist"
42 | ],
43 | "peerDependencies": {
44 | "webpack": "^5.0.0"
45 | },
46 | "devDependencies": {
47 | "@babel/cli": "^7.24.6",
48 | "@babel/core": "^7.24.6",
49 | "@babel/preset-env": "^7.24.6",
50 | "@commitlint/cli": "^18.6.1",
51 | "@commitlint/config-conventional": "^18.6.2",
52 | "@webpack-contrib/eslint-config-webpack": "^3.0.0",
53 | "cross-env": "^7.0.3",
54 | "cspell": "^8.8.3",
55 | "del": "^7.1.0",
56 | "del-cli": "^5.1.0",
57 | "eslint": "^8.57.0",
58 | "eslint-config-prettier": "^9.1.0",
59 | "eslint-plugin-import": "^2.29.1",
60 | "figlet": "^1.7.0",
61 | "husky": "^9.1.3",
62 | "jest": "^30.0.0",
63 | "lint-staged": "^15.2.5",
64 | "memfs": "^4.9.2",
65 | "modernizr": "^3.13.0",
66 | "npm-run-all": "^4.1.5",
67 | "prettier": "^3.3.0",
68 | "standard-version": "^9.5.0",
69 | "webpack": "^5.91.0"
70 | },
71 | "keywords": [
72 | "webpack",
73 | "loader",
74 | "execute",
75 | "val"
76 | ]
77 | }
78 |
--------------------------------------------------------------------------------
/.github/workflows/nodejs.yml:
--------------------------------------------------------------------------------
1 | name: val-loader
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | - next
8 | pull_request:
9 | branches:
10 | - master
11 | - next
12 |
13 | permissions:
14 | contents: read
15 |
16 | jobs:
17 | lint:
18 | name: Lint - ${{ matrix.os }} - Node v${{ matrix.node-version }}
19 |
20 | env:
21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22 |
23 | strategy:
24 | matrix:
25 | os: [ubuntu-latest]
26 | node-version: [lts/*]
27 |
28 | runs-on: ${{ matrix.os }}
29 |
30 | concurrency:
31 | group: lint-${{ matrix.os }}-v${{ matrix.node-version }}-${{ github.ref }}
32 | cancel-in-progress: true
33 |
34 | steps:
35 | - uses: actions/checkout@v4
36 | with:
37 | fetch-depth: 0
38 |
39 | - name: Use Node.js ${{ matrix.node-version }}
40 | uses: actions/setup-node@v4
41 | with:
42 | node-version: ${{ matrix.node-version }}
43 | cache: "npm"
44 |
45 | - name: Install dependencies
46 | run: npm ci
47 |
48 | - name: Lint
49 | run: npm run lint
50 |
51 | - name: Security audit
52 | run: npm run security
53 |
54 | - name: Validate PR commits with commitlint
55 | if: github.event_name == 'pull_request'
56 | run: npx commitlint --from ${{ github.event.pull_request.head.sha }}~${{ github.event.pull_request.commits }} --to ${{ github.event.pull_request.head.sha }} --verbose
57 |
58 | test:
59 | name: Test - ${{ matrix.os }} - Node v${{ matrix.node-version }}, Webpack ${{ matrix.webpack-version }}
60 |
61 | strategy:
62 | matrix:
63 | os: [ubuntu-latest, windows-latest, macos-latest]
64 | node-version: [18.x, 20.x, 22.x, 24.x]
65 | webpack-version: [latest]
66 |
67 | runs-on: ${{ matrix.os }}
68 |
69 | concurrency:
70 | group: test-${{ matrix.os }}-v${{ matrix.node-version }}-${{ matrix.webpack-version }}-${{ github.ref }}
71 | cancel-in-progress: true
72 |
73 | steps:
74 | - uses: actions/checkout@v4
75 |
76 | - name: Use Node.js ${{ matrix.node-version }}
77 | uses: actions/setup-node@v4
78 | with:
79 | node-version: ${{ matrix.node-version }}
80 | cache: "npm"
81 |
82 | - name: Install dependencies
83 | run: npm ci
84 |
85 | - name: Install webpack ${{ matrix.webpack-version }}
86 | if: matrix.webpack-version != 'latest'
87 | run: npm i webpack@${{ matrix.webpack-version }}
88 |
89 | - name: Run tests for webpack version ${{ matrix.webpack-version }}
90 | run: npm run test:coverage -- --ci
91 |
92 | - name: Submit coverage data to codecov
93 | uses: codecov/codecov-action@v5
94 | with:
95 | token: ${{ secrets.CODECOV_TOKEN }}
96 |
--------------------------------------------------------------------------------
/test/executableFile.test.js:
--------------------------------------------------------------------------------
1 | import path from "path";
2 |
3 | import { getCompiler, compile, readAsset, normalizeErrors } from "./helpers";
4 |
5 | describe("executableFile option", () => {
6 | it("should work with commonjs format", async () => {
7 | const compiler = getCompiler(
8 | "executableFileEntry.js",
9 | {},
10 | {
11 | module: {
12 | rules: [
13 | {
14 | test: /\.(json)$/i,
15 | rules: [
16 | {
17 | loader: require.resolve("./helpers/helperLoader.js"),
18 | },
19 | {
20 | loader: require.resolve("../src"),
21 | options: {
22 | executableFile: path.resolve(
23 | __dirname,
24 | "fixtures",
25 | "executableFile.js",
26 | ),
27 | },
28 | },
29 | ],
30 | },
31 | {
32 | test: /\.json$/i,
33 | type: "asset/resource",
34 | },
35 | ],
36 | },
37 | },
38 | );
39 | const stats = await compile(compiler);
40 |
41 | expect(readAsset("val-loader.js", compiler, stats)).toMatchSnapshot(
42 | "result",
43 | );
44 | expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
45 | "warnings",
46 | );
47 | expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot("errors");
48 | });
49 |
50 | // TODO jest have not good support for ES modules for testing it, tested manually
51 | it.skip("should work with ES modules format", async () => {
52 | const compiler = getCompiler(
53 | "executableFileEntry.js",
54 | {},
55 | {
56 | module: {
57 | rules: [
58 | {
59 | test: /\.(json)$/i,
60 | rules: [
61 | {
62 | loader: require.resolve("./helpers/helperLoader.js"),
63 | },
64 | {
65 | loader: require.resolve("../src"),
66 | options: {
67 | executableFile: path.resolve(
68 | __dirname,
69 | "fixtures",
70 | "executableFileES.mjs",
71 | ),
72 | },
73 | },
74 | ],
75 | },
76 | {
77 | test: /\.json$/i,
78 | type: "asset/resource",
79 | },
80 | ],
81 | },
82 | },
83 | );
84 | const stats = await compile(compiler);
85 |
86 | expect(readAsset("val-loader.js", compiler, stats)).toMatchSnapshot(
87 | "result",
88 | );
89 | expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
90 | "warnings",
91 | );
92 | expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot("errors");
93 | });
94 |
95 | it("should emit error", async () => {
96 | const compiler = getCompiler(
97 | "executableFileEntry.js",
98 | {},
99 | {
100 | module: {
101 | rules: [
102 | {
103 | test: /\.(json)$/i,
104 | rules: [
105 | {
106 | loader: require.resolve("./helpers/helperLoader.js"),
107 | },
108 | {
109 | loader: require.resolve("../src"),
110 | options: {
111 | executableFile: path.resolve(
112 | __dirname,
113 | "fixtures",
114 | "error-require.js",
115 | ),
116 | },
117 | },
118 | ],
119 | },
120 | {
121 | test: /\.json$/i,
122 | type: "asset/resource",
123 | },
124 | ],
125 | },
126 | },
127 | );
128 | const stats = await compile(compiler);
129 |
130 | expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
131 | "warnings",
132 | );
133 | expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot("errors");
134 | });
135 | });
136 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import Module from "module";
2 | import { pathToFileURL } from "url";
3 |
4 | import schema from "./options.json";
5 |
6 | const parentModule = module;
7 |
8 | function execute(code, loaderContext) {
9 | const module = new Module(loaderContext.resource, parentModule);
10 |
11 | // eslint-disable-next-line no-underscore-dangle
12 | module.paths = Module._nodeModulePaths(loaderContext.context);
13 | // Use the path without webpack-specific parts (`resourceQuery` or `resourceFragment`)
14 | module.filename = loaderContext.resourcePath;
15 |
16 | // eslint-disable-next-line no-underscore-dangle
17 | module._compile(code, loaderContext.resource);
18 |
19 | return module.exports;
20 | }
21 |
22 | function processResult(loaderContext, result) {
23 | if (!result || typeof result !== "object" || "code" in result === false) {
24 | loaderContext.callback(
25 | new Error(
26 | `The returned result of module "${loaderContext.resource}" is not an object with a "code" property`,
27 | ),
28 | );
29 |
30 | return;
31 | }
32 |
33 | if (
34 | typeof result.code !== "string" &&
35 | result.code instanceof Buffer === false
36 | ) {
37 | loaderContext.callback(
38 | new Error(
39 | `The returned code of module "${loaderContext.resource}" is neither a string nor an instance of Buffer`,
40 | ),
41 | );
42 |
43 | return;
44 | }
45 |
46 | (result.dependencies || []).forEach((dep) =>
47 | loaderContext.addDependency(dep),
48 | );
49 |
50 | (result.contextDependencies || []).forEach((dep) =>
51 | loaderContext.addContextDependency(dep),
52 | );
53 |
54 | (result.buildDependencies || []).forEach((dep) =>
55 | loaderContext.addBuildDependency(dep),
56 | );
57 |
58 | // Defaults to false which is a good default here because we assume that
59 | // results tend to be not cacheable when this loader is necessary
60 | loaderContext.cacheable(Boolean(result.cacheable));
61 |
62 | loaderContext.callback(
63 | null,
64 | result.code,
65 | result.sourceMap || null,
66 | result.ast || null,
67 | );
68 | }
69 |
70 | export default async function loader(content) {
71 | const options = this.getOptions(schema);
72 | const { executableFile } = options;
73 | const callback = this.async();
74 |
75 | let exports;
76 |
77 | if (executableFile) {
78 | try {
79 | // eslint-disable-next-line global-require,import/no-dynamic-require
80 | exports = require(executableFile);
81 | } catch (requireError) {
82 | try {
83 | let importESM;
84 |
85 | try {
86 | // eslint-disable-next-line no-new-func
87 | importESM = new Function("id", "return import(id);");
88 | } catch (e) {
89 | importESM = null;
90 | }
91 |
92 | if (
93 | requireError.code === "ERR_REQUIRE_ESM" &&
94 | pathToFileURL &&
95 | importESM
96 | ) {
97 | const urlForConfig = pathToFileURL(executableFile);
98 |
99 | exports = await importESM(urlForConfig);
100 | } else {
101 | throw requireError;
102 | }
103 | } catch (error) {
104 | callback(new Error(`Unable to require "${executableFile}": ${error}`));
105 |
106 | return;
107 | }
108 | }
109 | } else {
110 | try {
111 | exports = execute(content, this);
112 | } catch (error) {
113 | callback(new Error(`Unable to execute "${this.resource}": ${error}`));
114 |
115 | return;
116 | }
117 | }
118 |
119 | const func = exports && exports.default ? exports.default : exports;
120 |
121 | if (typeof func !== "function") {
122 | callback(
123 | new Error(
124 | `Module "${this.resource}" does not export a function as default`,
125 | ),
126 | );
127 | return;
128 | }
129 |
130 | let result;
131 |
132 | try {
133 | result = func(options, this, content);
134 | } catch (error) {
135 | callback(new Error(`Module "${this.resource}" throw error: ${error}`));
136 | return;
137 | }
138 |
139 | if (result && typeof result.then === "function") {
140 | result
141 | .then((res) => processResult(this, res))
142 | .catch((error) => {
143 | callback(new Error(`Module "${this.resource}" throw error: ${error}`));
144 | });
145 |
146 | return;
147 | }
148 |
149 | // No return necessary because processResult calls this.callback()
150 | processResult(this, result);
151 | }
152 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ## [6.0.0](https://github.com/webpack-contrib/val-loader/compare/v5.0.1...v6.0.0) (2024-01-15)
6 |
7 |
8 | ### ⚠ BREAKING CHANGES
9 |
10 | * minimum supported Node.js version is `18.12.0` ([#151](https://github.com/webpack-contrib/val-loader/issues/151)) ([ed762dc](https://github.com/webpack-contrib/val-loader/commit/ed762dcacd5aec8f462db8a7fa0da3c8d001f4b0))
11 |
12 | ### [5.0.1](https://github.com/webpack-contrib/val-loader/compare/v5.0.0...v5.0.1) (2022-11-29)
13 |
14 |
15 | ### Bug Fixes
16 |
17 | * compatibility with webpack cache ([#122](https://github.com/webpack-contrib/val-loader/issues/122)) ([41c08e3](https://github.com/webpack-contrib/val-loader/commit/41c08e3056741f9e0be1e4e45dc607a83d88b4e7))
18 |
19 | ## [5.0.0](https://github.com/webpack-contrib/val-loader/compare/v4.0.0...v5.0.0) (2022-05-17)
20 |
21 |
22 | ### ⚠ BREAKING CHANGES
23 |
24 | * minimum supported `Node.js` version is `14.15.0`
25 |
26 | ## [4.0.0](https://github.com/webpack-contrib/val-loader/compare/v3.1.0...v4.0.0) (2021-05-14)
27 |
28 |
29 | ### ⚠ BREAKING CHANGES
30 |
31 | * minimum supported `Node.js` version is `12.13.0`
32 |
33 | ## [3.1.0](https://github.com/webpack-contrib/val-loader/compare/v3.0.0...v3.1.0) (2021-03-01)
34 |
35 |
36 | ### Features
37 |
38 | * added the `buildDependensies` option ([#63](https://github.com/webpack-contrib/val-loader/issues/63)) ([04be3eb](https://github.com/webpack-contrib/val-loader/commit/04be3ebd9515358929c661b3c9db98ba3d870ac1))
39 | * added the `executableFile` option ([#65](https://github.com/webpack-contrib/val-loader/issues/65)) ([b46090f](https://github.com/webpack-contrib/val-loader/commit/b46090f323e3d2dcd75cbd552bd9447f98fd63e8))
40 | * support ECMA modules for the `executableFile` option ([#66](https://github.com/webpack-contrib/val-loader/issues/66)) ([1e6675f](https://github.com/webpack-contrib/val-loader/commit/1e6675fdf325c0973b1314fa3ad7984eaba197b9))
41 |
42 | ## [3.0.0](https://github.com/webpack-contrib/val-loader/compare/v2.1.2...v3.0.0) (2020-12-22)
43 |
44 |
45 | ### ⚠ BREAKING CHANGES
46 |
47 | * minimum supported webpack version is `5`
48 |
49 | ### [2.1.2](https://github.com/webpack-contrib/val-loader/compare/v2.1.1...v2.1.2) (2020-10-09)
50 |
51 | ### Chore
52 |
53 | * update `schema-utils`
54 |
55 | ### [2.1.1](https://github.com/webpack-contrib/val-loader/compare/v2.1.0...v2.1.1) (2020-04-09)
56 |
57 | ### Chore
58 |
59 | * update deps
60 |
61 | ## [2.1.0](https://github.com/webpack-contrib/val-loader/compare/v2.0.2...v2.1.0) (2019-12-17)
62 |
63 |
64 | ### Features
65 |
66 | * pass `loaderContext` as 2nd parameter ([#47](https://github.com/webpack-contrib/val-loader/issues/47)) ([cd5dd47](https://github.com/webpack-contrib/val-loader/commit/cd5dd471f41dc5dbb541e09ea8af0f3ed0ad23de))
67 |
68 | ### [2.0.2](https://github.com/webpack-contrib/val-loader/compare/v2.0.1...v2.0.2) (2019-11-25)
69 |
70 |
71 | ### Chore
72 |
73 | * add the `funding` field in `package.json`
74 |
75 |
76 |
77 | ### [2.0.1](https://github.com/webpack-contrib/val-loader/compare/v2.0.0...v2.0.1) (2019-11-19)
78 |
79 |
80 | ### Bug Fixes
81 |
82 | * link on package ([#44](https://github.com/webpack-contrib/val-loader/issues/44)) ([f234364](https://github.com/webpack-contrib/val-loader/commit/f234364a0c98f05fd0c4203c0a3946d6f0075adc))
83 |
84 | ### [2.0.0](https://github.com/webpack-contrib/val-loader/compare/v1.1.1...v2.0.0) (2019-11-14)
85 |
86 |
87 | ### Bug Fixes
88 |
89 | * support `webpack@5`
90 |
91 |
92 | ### Features
93 |
94 | * better handle errors from a module
95 | * pass `module.parent` to a module
96 | * validate loader options
97 |
98 |
99 | ### BREAKING CHANGES
100 |
101 | * minimum supported node version is `10.13.0`
102 | * minimum supported webpack version is `4.0.0`
103 |
104 |
105 |
106 |
107 | ## [1.1.1](https://github.com/webpack-contrib/val-loader/compare/v1.1.0...v1.1.1) (2018-06-21)
108 |
109 |
110 | ### Bug Fixes
111 |
112 | * add support for `webpack@4` ([#30](https://github.com/webpack-contrib/val-loader/issues/30)) ([fea518d](https://github.com/webpack-contrib/val-loader/commit/fea518d))
113 |
114 |
115 |
116 |
117 | # [1.1.0](https://github.com/webpack-contrib/val-loader/compare/v1.0.2...v1.1.0) (2017-11-19)
118 |
119 |
120 | ### Features
121 |
122 | * add support for `contextDependencies` in the `{Object}` interface (`options.contextDependencies`) ([#23](https://github.com/webpack-contrib/val-loader/issues/23)) ([78aa6fe](https://github.com/webpack-contrib/val-loader/commit/78aa6fe))
123 |
124 |
125 |
126 |
127 | ## [1.0.2](https://github.com/webpack-contrib/val-loader/compare/v1.0.1...v1.0.2) (2017-03-21)
128 |
129 |
130 | ### Bug Fixes
131 |
132 | * **.babelrc:** enable modules ([b0b116a](https://github.com/webpack-contrib/val-loader/commit/b0b116a))
133 |
134 |
135 |
136 |
137 | ## [1.0.1](https://github.com/webpack-contrib/val-loader/compare/v1.0.0...v1.0.1) (2017-03-20)
138 |
139 |
140 | ### Bug Fixes
141 |
142 | * **src:** add CJS wrapper ([cd043f5](https://github.com/webpack-contrib/val-loader/commit/cd043f5))
143 |
144 |
145 |
146 |
147 | # [1.0.0](https://github.com/webpack-contrib/val-loader/compare/v0.5.1...v1.0.0) (2017-03-16)
148 |
149 |
150 | ### Features
151 |
152 | * change expected module API ([caf2aab](https://github.com/webpack-contrib/val-loader/commit/caf2aab))
153 |
154 |
155 | ### BREAKING CHANGES
156 |
157 | * this commit introduces a major refactoring of the loader.
158 | * remove node 0.10 and node 0.12 support
159 | * the loaded module must now export a function
160 | * this function will be called with the loader options
161 | * this function must return an object with this structure
162 |
163 | Property | Type | Description
164 | :--------|:-----|:-----------
165 | `code` | `string|Buffer` | **Required**. The code that is passed to the next loader or to webpack.
166 | `sourceMap` | [`SourceMap`](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit) | **Optional**. Will be pased to the next loader or to webpack.
167 | `ast` | `any` | **Optional**. An [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) that will be passed to the next loader. Useful to speed up the build time if the next loader uses the same AST.
168 | `dependencies` | `Array` | **Default: `[]`**. An array of absolute, native paths to file dependencies that need to be watched for changes.
169 | `cacheable` | `boolean` | **Default: `false`**. Flag whether the code can be re-used in watch mode if none of the `dependencies` have changed.
170 |
171 | * the function may also return a promise for async results
172 | * switch tooling to webpack-defaults
173 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing in @webpack-contrib
2 |
3 | We'd always love contributions to further improve the webpack / webpack-contrib ecosystem!
4 | Here are the guidelines we'd like you to follow:
5 |
6 | - [Questions and Problems](#question)
7 | - [Issues and Bugs](#issue)
8 | - [Feature Requests](#feature)
9 | - [Pull Request Submission Guidelines](#submit-pr)
10 | - [Commit Message Conventions](#commit)
11 |
12 | ## Got a Question or Problem?
13 |
14 | Please submit support requests and questions to StackOverflow using the tag [[webpack]](http://stackoverflow.com/tags/webpack).
15 | StackOverflow is better suited for this kind of support though you may also inquire in [Webpack Gitter](https://gitter.im/webpack/webpack).
16 | The issue tracker is for bug reports and feature discussions.
17 |
18 | ## Found an Issue or Bug?
19 |
20 | Before you submit an issue, please search the issue tracker, an issue for your problem may already exist, and the discussion might inform you of workarounds readily available.
21 |
22 | We want to fix all the issues as soon as possible, but before fixing a bug, we need to reproduce and confirm it. In order to reproduce bugs, we ask that you provide a minimal reproduction scenario (GitHub repo or failing test case). Having a live, reproducible scenario gives us a wealth of important information without going back & forth to you with additional questions like:
23 |
24 | - version of Webpack used
25 | - version of the loader / plugin you are creating a bug report for
26 | - the use-case that fails
27 |
28 | A minimal reproduce scenario allows us to quickly confirm a bug (or point out config problems) as well as confirm that we are fixing the right problem.
29 |
30 | We will be insisting on a minimal reproduction scenario in order to save the maintainers' time and ultimately be able to fix more bugs. We understand that sometimes it might be hard to extract essential bits of code from a larger codebase, but we really need to isolate the problem before we can fix it.
31 |
32 | Unfortunately, we are unable to investigate or fix bugs without a minimal reproduction, so if we don't hear back from you, we may have to close an issue that doesn't have enough info to be reproduced.
33 |
34 | ## Feature Requests?
35 |
36 | You can _request_ a new feature by creating an issue on GitHub.
37 |
38 | If you would like to _implement_ a new feature yourself, please **first submit an issue** with a proposal to ensure the idea aligns with the goals of the project.
39 |
40 | ## Pull Request Submission Guidelines
41 |
42 | Before you submit your Pull Request (PR) consider the following guidelines:
43 |
44 | - Search GitHub for an open or closed PR related to your submission to avoid duplicating effort.
45 | - Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit). This is important because release notes are automatically generated from these messages.
46 | - Complete the `Pull Request Template`. Pull requests that ignore the template will not be reviewed.
47 | - Please sign the `Contributor License Agreement (CLA)` when you open your pull request. We cannot accept your contribution without it. Be sure to sign using the primary email address associated with your local and GitHub account.
48 |
49 | ## Webpack Contrib Commit Conventions
50 |
51 | Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
52 | format that includes a **type**, a **scope** and a **subject**:
53 |
54 | ```
55 | ():
56 |
57 |
58 |
59 |