From 1a9d7be6b728a0165a38559f6de6b16ee4439704 Mon Sep 17 00:00:00 2001 From: underfin Date: Wed, 19 Apr 2023 16:53:41 +0800 Subject: [PATCH] fix: test --- packages/rspack/package.json | 2 +- packages/rspack/tests/ConfigCase.template.ts | 762 ++++++++++++++++++ packages/rspack/tests/case.template.ts | 8 +- packages/rspack/tests/configCase.test.ts | 2 +- .../webpack.config.js | 1 - .../errors/compitable-errors-object/index.js | 4 +- .../output-module/simple/webpack.config.js | 8 +- .../parsing/node-stuff-plugin-off/index.js | 6 +- .../node-stuff-plugin-off/webpack.config.js | 2 +- .../umd/issue-15545/webpack.config.js | 2 +- .../rspack/tests/helpers/CurrentScript.js | 8 + packages/rspack/tests/helpers/asModule.js | 30 + .../tests/helpers/infrastructureLogErrors.js | 29 + 13 files changed, 843 insertions(+), 21 deletions(-) create mode 100644 packages/rspack/tests/ConfigCase.template.ts create mode 100644 packages/rspack/tests/helpers/CurrentScript.js create mode 100644 packages/rspack/tests/helpers/asModule.js create mode 100644 packages/rspack/tests/helpers/infrastructureLogErrors.js diff --git a/packages/rspack/package.json b/packages/rspack/package.json index e711a66a7f5..790eb22a540 100644 --- a/packages/rspack/package.json +++ b/packages/rspack/package.json @@ -9,7 +9,7 @@ "build": "tsc", "prepare": "pnpm precompile-schema", "dev": "tsc -w", - "test": "jest --runInBand", + "test": "node --experimental-vm-modules ../../node_modules/jest-cli/bin/jest --runInBand", "precompile-schema": "node ./scripts/precompile-schema.js" }, "files": [ diff --git a/packages/rspack/tests/ConfigCase.template.ts b/packages/rspack/tests/ConfigCase.template.ts new file mode 100644 index 00000000000..6cf1117844b --- /dev/null +++ b/packages/rspack/tests/ConfigCase.template.ts @@ -0,0 +1,762 @@ +"use strict"; +import { rspack, RspackOptions } from "../src"; +import assert from "assert"; + +const path = require("path"); +const fs = require("graceful-fs"); +const vm = require("vm"); +const { URL, pathToFileURL, fileURLToPath, parse } = require("url"); +const rimraf = require("rimraf"); +const checkArrayExpectation = require("./checkArrayExpectation"); +const createLazyTestEnv = require("./helpers/createLazyTestEnv"); +const deprecationTracking = require("./helpers/deprecationTracking"); +const FakeDocument = require("./helpers/FakeDocument"); +const CurrentScript = require("./helpers/CurrentScript"); + +const prepareOptions = require("./helpers/prepareOptions"); +// const { parseResource } = require("../lib/util/identifier"); +const captureStdio = require("./helpers/captureStdio"); +const asModule = require("./helpers/asModule"); +const filterInfraStructureErrors = require("./helpers/infrastructureLogErrors"); +// fake define +const define = function (...args) { + const factory = args.pop(); + factory(); +}; + +const casesPath = path.join(__dirname, "configCases"); +const categories = fs.readdirSync(casesPath).map(cat => { + return { + name: cat, + tests: fs + .readdirSync(path.join(casesPath, cat)) + .filter(folder => !folder.startsWith("_")) + // exclude outdate test + .filter(folder => + [".js", ".jsx", ".ts", ".tsx"].some(ext => { + return fs.existsSync( + path.join(casesPath, cat, folder, "index" + ext) + ); + }) + ) + .sort() + }; +}); + +const createLogger = appendTarget => { + return { + log: l => appendTarget.push(l), + debug: l => appendTarget.push(l), + trace: l => appendTarget.push(l), + info: l => appendTarget.push(l), + warn: console.warn.bind(console), + error: console.error.bind(console), + logTime: () => {}, + group: () => {}, + groupCollapsed: () => {}, + groupEnd: () => {}, + profile: () => {}, + profileEnd: () => {}, + clear: () => {}, + status: () => {} + }; +}; + +export const describeCases = config => { + describe(config.name, () => { + let stderr; + beforeEach(() => { + stderr = captureStdio(process.stderr, true); + }); + afterEach(() => { + stderr.restore(); + }); + jest.setTimeout(20000); + + for (const category of categories) { + // eslint-disable-next-line no-loop-func + describe(category.name, () => { + for (const testName of category.tests) { + // eslint-disable-next-line no-loop-func + describe(testName, function () { + const testDirectory = path.join(casesPath, category.name, testName); + const filterPath = path.join(testDirectory, "test.filter.js"); + if (fs.existsSync(filterPath) && !require(filterPath)()) { + describe.skip(testName, () => { + it("filtered", () => {}); + }); + return; + } + const infraStructureLog = []; + const outBaseDir = path.join(__dirname, "js"); + const testSubPath = path.join(config.name, category.name, testName); + // const outputDirectory = path.join(outBaseDir, testSubPath); + const outputDirectory = path.join(testDirectory, "dist"); + const cacheDirectory = path.join(outBaseDir, ".cache", testSubPath); + let options, optionsArr, testConfig, configFile; + beforeAll(() => { + configFile = path.join(testDirectory, "webpack.config.js"); + options = {}; + if (fs.existsSync(configFile)) { + options = prepareOptions(require(configFile), { + testPath: outputDirectory + }); + } + optionsArr = [].concat(options); + optionsArr.forEach((options, idx) => { + if (!options.context) options.context = testDirectory; + if (!options.mode) options.mode = "development"; + // if (!options.optimization) options.optimization = {}; + // if (options.optimization.minimize === undefined) + // options.optimization.minimize = false; + // if (options.optimization.minimizer === undefined) { + // options.optimization.minimizer = [ + // new (require("terser-webpack-plugin"))({ + // parallel: false + // }) + // ]; + // } + if (!options.entry) + options.entry = { + main: "./" + }; + if (!options.target) options.target = "node"; + if (!options.output) options.output = {}; + if (!options.output.path) options.output.path = outputDirectory; + // if (typeof options.output.pathinfo === "undefined") + // options.output.pathinfo = true; + // if (!options.output.filename) + // options.output.filename = + // "bundle" + + // idx + + // (options.experiments && options.experiments.outputModule + // ? ".mjs" + // : ".js"); + // if (config.cache) { + // options.cache = { + // cacheDirectory, + // name: `config-${idx}`, + // ...config.cache + // }; + // options.infrastructureLogging = { + // debug: true, + // console: createLogger(infraStructureLog) + // }; + // } + // if (!options.snapshot) options.snapshot = {}; + // if (!options.snapshot.managedPaths) { + // options.snapshot.managedPaths = [ + // path.resolve(__dirname, "../node_modules") + // ]; + // } + }); + testConfig = { + findBundle: function (i, options) { + // const ext = path.extname( + // parse(options.output.filename).path + // ); + // if ( + // fs.existsSync( + // path.join(options.output.path, "bundle" + i + ext) + // ) + // ) { + // return "./bundle" + i + ext; + // } + return "./main.js"; + } + // timeout: 30000 + }; + try { + // try to load a test file + testConfig = Object.assign( + testConfig, + require(path.join(testDirectory, "test.config.js")) + ); + } catch (e) { + // ignored + } + // if (testConfig.timeout) setDefaultTimeout(testConfig.timeout); + }); + afterAll(() => { + // cleanup + options = undefined; + optionsArr = undefined; + testConfig = undefined; + }); + beforeAll(() => { + rimraf.sync(cacheDirectory); + }); + const handleFatalError = (err, done) => { + const fakeStats = { + errors: [ + { + message: err.message, + stack: err.stack + } + ] + }; + if ( + checkArrayExpectation( + testDirectory, + fakeStats, + "error", + "Error", + done + ) + ) { + return; + } + // Wait for uncaught errors to occur + // setTimeout(done, 200); + return; + }; + // if (config.cache) { + // it(`${testName} should pre-compile to fill disk cache (1st)`, done => { + // rimraf.sync(outputDirectory); + // fs.mkdirSync(outputDirectory, { recursive: true }); + // infraStructureLog.length = 0; + // const deprecationTracker = deprecationTracking.start(); + // require("..")(options, err => { + // deprecationTracker(); + // const infrastructureLogging = stderr.toString(); + // if (infrastructureLogging) { + // return done( + // new Error( + // "Errors/Warnings during build:\n" + + // infrastructureLogging + // ) + // ); + // } + // const infrastructureLogErrors = filterInfraStructureErrors( + // infraStructureLog, + // { + // run: 1, + // options + // } + // ); + // if ( + // infrastructureLogErrors.length && + // checkArrayExpectation( + // testDirectory, + // { infrastructureLogs: infrastructureLogErrors }, + // "infrastructureLog", + // "infrastructure-log", + // "InfrastructureLog", + // done + // ) + // ) { + // return; + // } + // if (err) return handleFatalError(err, done); + // done(); + // }); + // }, 60000); + // it(`${testName} should pre-compile to fill disk cache (2nd)`, done => { + // rimraf.sync(outputDirectory); + // fs.mkdirSync(outputDirectory, { recursive: true }); + // infraStructureLog.length = 0; + // const deprecationTracker = deprecationTracking.start(); + // require("..")(options, (err, stats) => { + // deprecationTracker(); + // if (err) return handleFatalError(err, done); + // const { modules, children, errorsCount } = stats.toJson({ + // all: false, + // modules: true, + // errorsCount: true + // }); + // if (errorsCount === 0) { + // const infrastructureLogging = stderr.toString(); + // if (infrastructureLogging) { + // return done( + // new Error( + // "Errors/Warnings during build:\n" + + // infrastructureLogging + // ) + // ); + // } + // const allModules = children + // ? children.reduce( + // (all, { modules }) => all.concat(modules), + // modules || [] + // ) + // : modules; + // if ( + // allModules.some( + // m => m.type !== "cached modules" && !m.cached + // ) + // ) { + // return done( + // new Error( + // `Some modules were not cached:\n${stats.toString({ + // all: false, + // modules: true, + // modulesSpace: 100 + // })}` + // ) + // ); + // } + // } + // const infrastructureLogErrors = filterInfraStructureErrors( + // infraStructureLog, + // { + // run: 2, + // options + // } + // ); + // if ( + // infrastructureLogErrors.length && + // checkArrayExpectation( + // testDirectory, + // { infrastructureLogs: infrastructureLogErrors }, + // "infrastructureLog", + // "infrastructure-log", + // "InfrastructureLog", + // done + // ) + // ) { + // return; + // } + // done(); + // }); + // }, 40000); + // } + it(`${testName} should compile`, done => { + rimraf.sync(outputDirectory); + fs.mkdirSync(outputDirectory, { recursive: true }); + infraStructureLog.length = 0; + const deprecationTracker = deprecationTracking.start(); + const onCompiled = (err, stats) => { + const deprecations = deprecationTracker(); + if (err) return handleFatalError(err, done); + const statOptions = { + preset: "verbose", + colors: false + }; + fs.mkdirSync(outputDirectory, { recursive: true }); + // fs.writeFileSync( + // path.join(outputDirectory, "stats.txt"), + // stats.toString(statOptions), + // "utf-8" + // ); + const jsonStats = stats.toJson({ + errorDetails: true + }); + // fs.writeFileSync( + // path.join(outputDirectory, "stats.json"), + // JSON.stringify(jsonStats, null, 2), + // "utf-8" + // ); + // error case not expect error + if (category.name === "errors") { + assert(jsonStats.errors!.length > 0); + } else if (category.name === "warnings") { + assert(jsonStats.warnings!.length > 0); + } else { + if (jsonStats.errors!.length > 0) { + console.log( + `case: ${testName}\nerrors:\n`, + `${jsonStats.errors!.map(x => x.message).join("\n")}` + ); + } + assert( + jsonStats.errors!.length === 0, + `${JSON.stringify(jsonStats.errors, null, 2)}` + ); + } + // if ( + // checkArrayExpectation( + // testDirectory, + // jsonStats, + // "error", + // "Error", + // done + // ) + // ) { + // return; + // } + // if ( + // checkArrayExpectation( + // testDirectory, + // jsonStats, + // "warning", + // "Warning", + // done + // ) + // ) { + // return; + // } + const infrastructureLogging = stderr.toString(); + if (infrastructureLogging) { + return done( + new Error( + "Errors/Warnings during build:\n" + infrastructureLogging + ) + ); + } + if ( + checkArrayExpectation( + testDirectory, + { deprecations }, + "deprecation", + "Deprecation", + done + ) + ) { + return; + } + const infrastructureLogErrors = filterInfraStructureErrors( + infraStructureLog, + { + run: 3, + options + } + ); + if ( + infrastructureLogErrors.length && + checkArrayExpectation( + testDirectory, + { infrastructureLogs: infrastructureLogErrors }, + "infrastructureLog", + "infrastructure-log", + "InfrastructureLog", + done + ) + ) { + return; + } + + let filesCount = 0; + if (testConfig.noTests) return process.nextTick(done); + if (testConfig.beforeExecute) testConfig.beforeExecute(); + const results = []; + for (let i = 0; i < optionsArr.length; i++) { + const options = optionsArr[i]; + const bundlePath = testConfig.findBundle(i, optionsArr[i]); + if (bundlePath) { + filesCount++; + const document = new FakeDocument(outputDirectory); + const globalContext = { + console: console, + expect: expect, + setTimeout: setTimeout, + clearTimeout: clearTimeout, + document, + getComputedStyle: + document.getComputedStyle.bind(document), + location: { + href: "https://test.cases/path/index.html", + origin: "https://test.cases", + toString() { + return "https://test.cases/path/index.html"; + } + } + }; + + const requireCache = Object.create(null); + const esmCache = new Map(); + const esmIdentifier = `${category.name}-${testName}-${i}`; + const baseModuleScope = { + console: console, + it: _it, + beforeEach: _beforeEach, + afterEach: _afterEach, + expect, + jest, + __STATS__: jsonStats, + nsObj: m => { + Object.defineProperty(m, Symbol.toStringTag, { + value: "Module" + }); + return m; + } + }; + + let runInNewContext = false; + if ( + options.target === "web" || + options.target === "webworker" + ) { + // @ts-ignore + baseModuleScope.window = globalContext; + // @ts-ignore + baseModuleScope.self = globalContext; + // @ts-ignore + baseModuleScope.URL = URL; + // @ts-ignore + baseModuleScope.Worker = + require("./helpers/createFakeWorker")({ + outputDirectory + }); + runInNewContext = true; + } + if (testConfig.moduleScope) { + testConfig.moduleScope(baseModuleScope); + } + const esmContext = vm.createContext(baseModuleScope, { + name: "context for esm" + }); + + // eslint-disable-next-line no-loop-func + const _require = ( + currentDirectory, + options, + module, + esmMode, + parentModule + ) => { + if (testConfig === undefined) { + throw new Error( + `_require(${module}) called after all tests from ${category.name} ${testName} have completed` + ); + } + if (Array.isArray(module) || /^\.\.?\//.test(module)) { + let content; + let p; + let subPath = ""; + if (Array.isArray(module)) { + p = path.join(currentDirectory, ".array-require.js"); + content = `module.exports = (${module + .map(arg => { + return `require(${JSON.stringify(`./${arg}`)})`; + }) + .join(", ")});`; + } else { + p = path.join(currentDirectory, module); + content = fs.readFileSync(p, "utf-8"); + const lastSlash = module.lastIndexOf("/"); + let firstSlash = module.indexOf("/"); + + if (lastSlash !== -1 && firstSlash !== lastSlash) { + if (firstSlash !== -1) { + let next = module.indexOf("/", firstSlash + 1); + let dir = module.slice(firstSlash + 1, next); + + while (dir === ".") { + firstSlash = next; + next = module.indexOf("/", firstSlash + 1); + dir = module.slice(firstSlash + 1, next); + } + } + + subPath = module.slice( + firstSlash + 1, + lastSlash + 1 + ); + } + } + const isModule = + // p.endsWith(".mjs") && + options.experiments && + options.experiments.outputModule; + + if (isModule) { + if (!vm.SourceTextModule) + throw new Error( + "Running this test requires '--experimental-vm-modules'.\nRun with 'node --experimental-vm-modules node_modules/jest-cli/bin/jest'." + ); + let esm = esmCache.get(p); + if (!esm) { + esm = new vm.SourceTextModule(content, { + identifier: esmIdentifier + "-" + p, + url: pathToFileURL(p).href + "?" + esmIdentifier, + context: esmContext, + initializeImportMeta: (meta, module) => { + meta.url = pathToFileURL(p).href; + }, + importModuleDynamically: async ( + specifier, + module + ) => { + const result = await _require( + path.dirname(p), + options, + specifier, + "evaluated", + module + ); + return await asModule(result, module.context); + } + }); + esmCache.set(p, esm); + } + if (esmMode === "unlinked") return esm; + return (async () => { + await esm.link( + async (specifier, referencingModule) => { + return await asModule( + await _require( + path.dirname( + referencingModule.identifier + ? referencingModule.identifier.slice( + esmIdentifier.length + 1 + ) + : fileURLToPath(referencingModule.url) + ), + options, + specifier, + "unlinked", + referencingModule + ), + referencingModule.context, + true + ); + } + ); + // node.js 10 needs instantiate + if (esm.instantiate) esm.instantiate(); + await esm.evaluate(); + if (esmMode === "evaluated") return esm; + const ns = esm.namespace; + return ns.default && ns.default instanceof Promise + ? ns.default + : ns; + })(); + } else { + if (p in requireCache) { + return requireCache[p].exports; + } + const m = { + exports: {} + }; + requireCache[p] = m; + const moduleScope = { + ...baseModuleScope, + require: _require.bind( + null, + path.dirname(p), + options + ), + importScripts: url => { + expect(url).toMatch( + /^https:\/\/test\.cases\/path\// + ); + // @ts-ignore + _require( + outputDirectory, + options, + `.${url.slice( + "https://test.cases/path".length + )}` + ); + }, + module: m, + exports: m.exports, + __dirname: path.dirname(p), + __filename: p, + _globalAssign: { expect }, + define + }; + if (testConfig.moduleScope) { + testConfig.moduleScope(moduleScope); + } + if (!runInNewContext) + content = `Object.assign(global, _globalAssign);\n ${content}`; + const args = Object.keys(moduleScope); + const argValues = args.map(arg => moduleScope[arg]); + const code = `(function(${args.join( + ", " + )}) {${content}\n})`; + + let oldCurrentScript = document.currentScript; + document.currentScript = new CurrentScript(subPath); + const fn = runInNewContext + ? vm.runInNewContext(code, globalContext, p) + : vm.runInThisContext(code, p); + debugger; + fn.call( + testConfig.nonEsmThis + ? testConfig.nonEsmThis(module) + : m.exports, + ...argValues + ); + document.currentScript = oldCurrentScript; + return m.exports; + } + } else if ( + testConfig.modules && + module in testConfig.modules + ) { + return testConfig.modules[module]; + } else { + return require(module.startsWith("node:") + ? module.slice(5) + : module); + } + }; + if (Array.isArray(bundlePath)) { + for (const bundlePathItem of bundlePath) { + results.push( + // @ts-ignore + _require( + outputDirectory, + options, + "./" + bundlePathItem + ) + ); + } + } else { + results.push( + // @ts-ignore + _require(outputDirectory, options, bundlePath) + ); + } + } + } + // give a free pass to compilation that generated an error + if ( + !jsonStats.errors.length && + filesCount !== optionsArr.length + ) { + return done( + new Error( + "Should have found at least one bundle file per webpack config" + ) + ); + } + Promise.all(results) + .then(() => { + if (testConfig.afterExecute) testConfig.afterExecute(); + for (const key of Object.keys(global)) { + if (key.includes("webpack")) delete global[key]; + } + if (getNumberOfTests() < filesCount) { + return done(new Error("No tests exported by test case")); + } + done(); + }) + .catch(done); + }; + // if (config.cache) { + // try { + // const compiler = require("..")(options); + // compiler.run(err => { + // if (err) return handleFatalError(err, done); + // compiler.run((error, stats) => { + // compiler.close(err => { + // if (err) return handleFatalError(err, done); + // onCompiled(error, stats); + // }); + // }); + // }); + // } catch (e) { + // handleFatalError(e, done); + // } + // } else { + // require("..")(options, onCompiled); + // } + rspack(optionsArr, onCompiled); + } /* 30000 */); + + const { + it: _it, + beforeEach: _beforeEach, + afterEach: _afterEach, + setDefaultTimeout, + getNumberOfTests + } = createLazyTestEnv(10000); + }); + } + }); + } + }); +}; diff --git a/packages/rspack/tests/case.template.ts b/packages/rspack/tests/case.template.ts index 9a0e5a2eff8..01de46649a8 100644 --- a/packages/rspack/tests/case.template.ts +++ b/packages/rspack/tests/case.template.ts @@ -6,11 +6,6 @@ import { rspack, RspackOptions } from "../src"; import assert from "assert"; import createLazyTestEnv from "./helpers/createLazyTestEnv"; -const define = function (...args) { - const factory = args.pop(); - factory(); -}; - // most of these could be removed when we support external builtins by default export function describeCases(config: { name: string; casePath: string }) { const casesPath = path.resolve(__dirname, config.casePath); @@ -134,8 +129,7 @@ export function describeCases(config: { name: string; casePath: string }) { bundlePath, _it, expect, - jest, - define + jest ); return m.exports; }); diff --git a/packages/rspack/tests/configCase.test.ts b/packages/rspack/tests/configCase.test.ts index 6609ef0985f..bea33f1abdd 100644 --- a/packages/rspack/tests/configCase.test.ts +++ b/packages/rspack/tests/configCase.test.ts @@ -1,4 +1,4 @@ -import { describeCases } from "./case.template"; +import { describeCases } from "./ConfigCase.template"; describeCases({ name: "configCases", casePath: "configCases" diff --git a/packages/rspack/tests/configCases/builtins/html-with-output-public-path/webpack.config.js b/packages/rspack/tests/configCases/builtins/html-with-output-public-path/webpack.config.js index e3d91d9366b..c387e508bd8 100644 --- a/packages/rspack/tests/configCases/builtins/html-with-output-public-path/webpack.config.js +++ b/packages/rspack/tests/configCases/builtins/html-with-output-public-path/webpack.config.js @@ -1,6 +1,5 @@ module.exports = { output: { - path: "./dist", publicPath: "/base" }, builtins: { diff --git a/packages/rspack/tests/configCases/errors/compitable-errors-object/index.js b/packages/rspack/tests/configCases/errors/compitable-errors-object/index.js index 57d2a94ffb1..003115bd59e 100644 --- a/packages/rspack/tests/configCases/errors/compitable-errors-object/index.js +++ b/packages/rspack/tests/configCases/errors/compitable-errors-object/index.js @@ -1 +1,3 @@ -console.log('hello') \ No newline at end of file +it("should run", () => { + console.log('hello'); +}) \ No newline at end of file diff --git a/packages/rspack/tests/configCases/output-module/simple/webpack.config.js b/packages/rspack/tests/configCases/output-module/simple/webpack.config.js index 988751fa806..c388f2ae4c1 100644 --- a/packages/rspack/tests/configCases/output-module/simple/webpack.config.js +++ b/packages/rspack/tests/configCases/output-module/simple/webpack.config.js @@ -3,10 +3,10 @@ module.exports = { output: { filename: "[name].js", chunkFormat: "module", - chunkLoading: "import" - // library: { - // type: 'module' - // } + chunkLoading: "import", + library: { + type: "module" + } }, experiments: { outputModule: true diff --git a/packages/rspack/tests/configCases/parsing/node-stuff-plugin-off/index.js b/packages/rspack/tests/configCases/parsing/node-stuff-plugin-off/index.js index b2e9beb68cc..d8e066395e9 100644 --- a/packages/rspack/tests/configCases/parsing/node-stuff-plugin-off/index.js +++ b/packages/rspack/tests/configCases/parsing/node-stuff-plugin-off/index.js @@ -1,8 +1,6 @@ it("should not evaluate __dirname or __filename when node option is false", function (done) { - console.log(__dirname, __filename); - var fs = require("fs"); - var source = fs.readFileSync(__filename, "utf-8"); - expect(source.includes("console.log(__dirname, __filename)")).toBe(true); + expect(typeof __dirname).toBe("undefined"); + expect(typeof __filename).toBe("undefined"); // if (typeof __dirname !== "undefined") { // done.fail(); // } diff --git a/packages/rspack/tests/configCases/parsing/node-stuff-plugin-off/webpack.config.js b/packages/rspack/tests/configCases/parsing/node-stuff-plugin-off/webpack.config.js index 81b36089f90..0c8b672e367 100644 --- a/packages/rspack/tests/configCases/parsing/node-stuff-plugin-off/webpack.config.js +++ b/packages/rspack/tests/configCases/parsing/node-stuff-plugin-off/webpack.config.js @@ -1,5 +1,5 @@ /** @type {import("../../../../").Configuration} */ module.exports = { - // target: "web", + target: "web", node: false }; diff --git a/packages/rspack/tests/configCases/umd/issue-15545/webpack.config.js b/packages/rspack/tests/configCases/umd/issue-15545/webpack.config.js index 73b1025f8b4..0c772d0ee7e 100644 --- a/packages/rspack/tests/configCases/umd/issue-15545/webpack.config.js +++ b/packages/rspack/tests/configCases/umd/issue-15545/webpack.config.js @@ -10,7 +10,7 @@ module.exports = { libraryTarget: "umd", chunkLoading: "jsonp", chunkFormat: "array-push", - globalObject: "this" + globalObject: "global" }, optimization: { minimize: false, diff --git a/packages/rspack/tests/helpers/CurrentScript.js b/packages/rspack/tests/helpers/CurrentScript.js new file mode 100644 index 00000000000..b198c1b583f --- /dev/null +++ b/packages/rspack/tests/helpers/CurrentScript.js @@ -0,0 +1,8 @@ +class CurrentScript { + constructor(path = "", type = "text/javascript") { + this.src = `https://test.cases/path/${path}index.js`; + this.type = type; + } +} + +module.exports = CurrentScript; diff --git a/packages/rspack/tests/helpers/asModule.js b/packages/rspack/tests/helpers/asModule.js new file mode 100644 index 00000000000..1598ce06d13 --- /dev/null +++ b/packages/rspack/tests/helpers/asModule.js @@ -0,0 +1,30 @@ +const vm = require("vm"); + +const SYNTHETIC_MODULES_STORE = "__SYNTHETIC_MODULES_STORE"; + +module.exports = async (something, context, unlinked) => { + if ( + something instanceof (vm.Module || /* node.js 10 */ vm.SourceTextModule) + ) { + return something; + } + context[SYNTHETIC_MODULES_STORE] = context[SYNTHETIC_MODULES_STORE] || []; + const i = context[SYNTHETIC_MODULES_STORE].length; + context[SYNTHETIC_MODULES_STORE].push(something); + const code = [...new Set(["default", ...Object.keys(something)])] + .map( + name => + `const _${name} = ${SYNTHETIC_MODULES_STORE}[${i}]${ + name === "default" ? "" : `[${JSON.stringify(name)}]` + }; export { _${name} as ${name}};` + ) + .join("\n"); + const m = new vm.SourceTextModule(code, { + context + }); + if (unlinked) return m; + await m.link(() => {}); + if (m.instantiate) m.instantiate(); + await m.evaluate(); + return m; +}; diff --git a/packages/rspack/tests/helpers/infrastructureLogErrors.js b/packages/rspack/tests/helpers/infrastructureLogErrors.js new file mode 100644 index 00000000000..58e778b0098 --- /dev/null +++ b/packages/rspack/tests/helpers/infrastructureLogErrors.js @@ -0,0 +1,29 @@ +"use strict"; + +const PERSISTENCE_CACHE_INVALIDATE_ERROR = (log, config) => { + if (config.run < 2) return; + const match = + /^\[webpack\.cache\.PackFileCacheStrategy\] Pack got invalid because of write to:(.+)$/.exec( + log + ); + if (match) { + return `Pack got invalid because of write to: ${match[1].trim()}`; + } +}; +const errorsFilter = [PERSISTENCE_CACHE_INVALIDATE_ERROR]; + +/** + * @param {string[]} logs logs + * @param {object} config config + * @returns {string[]} errors + */ +module.exports = function filterInfraStructureErrors(logs, config) { + const results = []; + for (const log of logs) { + for (const filter of errorsFilter) { + const result = filter(log, config); + if (result) results.push({ message: result }); + } + } + return results; +};