diff --git a/README.md b/README.md index 850fd83..35aa37c 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,95 @@ -# nextjs-node-loader - -This is a custom loader for Webpack that allows you to include native Node.js `.node` modules in your Next.js project. -It simplifies the process of loading native modules by providing a standardized interface that works seamlessly with -Next.js. -This is a modified version of [Node loader](https://github.com/webpack-contrib/node-loader). -More context on the [why and example use of the loader in my blog post](https://www.amarjanica.com/nextjs-and-rust-creating-a-custom-webpack-loader-for-native-node-modules). - -## Getting Started - -To begin, you'll need to install a `nextjs-node-loader`: - -```console -npm install nextjs-node-loader --save-dev -``` - -**next.config.js** - -```js -module.exports = { - webpack: (config, { dev, isServer, webpack, nextRuntime }) => { - config.module.rules.push({ - test: /\.node$/, - use: [ - { - loader: "nextjs-node-loader", - options: { - flags: os.constants.dlopen.RTLD_NOW, - outputPath: config.output.path - } - }, - ], - }); - return config; - }, -}; -``` - -And use in e.g. your api route; - -```javascript -import module from "node-module"; - -export default function handler(req, res) { - // ... -} -``` - -## Options - -| Name | Type | Default | Description | -|:----------:|:----------:|:--------------------:| :---------------------------------------------------- | -| flags | `{Number}` | `undefined` | Enables/Disables `url`/`image-set` functions handling | -| outputPath | `{String}` | webpack's outputPath | The root path of shared node libraries | -| includeWebpackPublicPath | `{String}`| false | If __webpack_public_path__ should be included in a path for loading node module. For nextjs >13.2.5 should be false. | - -## License - -[MIT](./LICENSE) +# nextjs-node-loader (No Longer Maintained) + +**Status: Deprecated** + +There's no need for it anymore. I've added an example in [next 14](./examples/next-14) to demo including different native modules. +Solution in NextJS 14 is to add a: +```javascript +experimental: { + serverComponentsExternalPackages: ['yournativemodule'], +} +``` +For a dependency built with neon bindings, you might also need to configure `externals`: +```javascript +/** @type {import('next').NextConfig} */ +const nextConfig = { + experimental: { + serverComponentsExternalPackages: ['mynativemodule'], + }, + /** @type {import('webpack').Configuration} */ + webpack: (config, context) => { + if (context.isServer) { + config.externals = [ + ...config.externals, + {'mynativemodule': 'commonjs mynativemodule'}, + ] + } + return config; + }, +}; +``` + +A huge thank you to everyone who contributed to this project! ❤️ + +For historical purposes, the original README is preserved below. + + +# nextjs-node-loader + +This is a custom loader for Webpack that allows you to include native Node.js `.node` modules in your Next.js project. +It simplifies the process of loading native modules by providing a standardized interface that works seamlessly with +Next.js. +This is a modified version of [Node loader](https://github.com/webpack-contrib/node-loader). +More context on the [why and example use of the loader in my blog post](https://www.amarjanica.com/nextjs-and-rust-creating-a-custom-webpack-loader-for-native-node-modules). + +## Getting Started + +To begin, you'll need to install a `nextjs-node-loader`: + +```console +npm install nextjs-node-loader --save-dev +``` + +**next.config.js** + +```js +module.exports = { + webpack: (config, { dev, isServer, webpack, nextRuntime }) => { + config.module.rules.push({ + test: /\.node$/, + use: [ + { + loader: "nextjs-node-loader", + options: { + flags: os.constants.dlopen.RTLD_NOW, + outputPath: config.output.path + } + }, + ], + }); + return config; + }, +}; +``` + +And use in e.g. your api route; + +```javascript +import module from "node-module"; + +export default function handler(req, res) { + // ... +} +``` + +## Options + +| Name | Type | Default | Description | +|:----------:|:----------:|:--------------------:| :---------------------------------------------------- | +| flags | `{Number}` | `undefined` | Enables/Disables `url`/`image-set` functions handling | +| outputPath | `{String}` | webpack's outputPath | The root path of shared node libraries | +| includeWebpackPublicPath | `{String}`| false | If __webpack_public_path__ should be included in a path for loading node module. For nextjs >13.2.5 should be false. | + +## License + +[MIT](./LICENSE) diff --git a/examples/next-14/app/api/msnodesqlv8/route.ts b/examples/next-14/app/api/msnodesqlv8/route.ts new file mode 100644 index 0000000..f75eac3 --- /dev/null +++ b/examples/next-14/app/api/msnodesqlv8/route.ts @@ -0,0 +1,6 @@ +import msnodesql from 'msnodesqlv8'; + +export async function GET() { + console.log(msnodesql) + return Response.json({'status': 'ok'}); +} diff --git a/examples/next-14/app/api/slugify/[slug]/route.ts b/examples/next-14/app/api/slugify/[slug]/route.ts index 08c5044..b19132b 100644 --- a/examples/next-14/app/api/slugify/[slug]/route.ts +++ b/examples/next-14/app/api/slugify/[slug]/route.ts @@ -6,6 +6,5 @@ export async function GET( { params }: { params: { slug: string } } ) { const slug = slugifier.slugify(params.slug); - return Response.json({message: slug}); } diff --git a/examples/next-14/inspectnext.js b/examples/next-14/inspectnext.js new file mode 100644 index 0000000..51c342a --- /dev/null +++ b/examples/next-14/inspectnext.js @@ -0,0 +1,41 @@ +const path = require("path"); +const nextBuild = require('next/dist/build').default; + +async function inspectWebpackConfig() { + const appDir = path.resolve(__dirname); + const debugOutput = true; + const runLint = false; + const noMangling = true; + const appDirOnly = true; + const turboNextBuild = false; + const experimentalBuildMode = false; + + try { + void await nextBuild(appDir, { + + // Hook into the webpack configuration before it builds + webpack(config, { isServer }) { + // Inspect or modify the webpack configuration here + console.log('Inspecting Webpack configuration...'); + console.log(config); + + // Optionally, save the Webpack config to a file for easier inspection + fs.writeFileSync( + path.join(__dirname, 'webpack-config.json'), + JSON.stringify(config, null, 2) + ); + + console.log('Webpack config saved to webpack-config.json'); + + // Return the modified or original config + return config; + }, + }, debugOutput, runLint, noMangling, appDirOnly, turboNextBuild, experimentalBuildMode); + + console.log('Next.js build completed successfully.'); + } catch (error) { + console.error('Error during Next.js build:', error); + } +} + +inspectWebpackConfig(); diff --git a/examples/next-14/next.config.mjs b/examples/next-14/next.config.mjs index 63c1918..a7a9708 100644 --- a/examples/next-14/next.config.mjs +++ b/examples/next-14/next.config.mjs @@ -1,21 +1,16 @@ -import os from 'os'; - /** @type {import('next').NextConfig} */ const nextConfig = { - webpack: (config) => { - config.module.rules.push({ - test: /\.node$/, - use: [ - { - loader: 'nextjs-node-loader', - options: { - flags: os.constants.dlopen.RTLD_NOW, - outputPath: config.output.path - }, - }, - ], - }); - + experimental: { + serverComponentsExternalPackages: ['msnodesqlv8','robotjs', 'node-el-slugify'], + }, + /** @type {import('webpack').Configuration} */ + webpack: (config, context) => { + if (context.isServer) { + config.externals = [ + ...config.externals, + {'node-el-slugify': 'commonjs node-el-slugify'}, + ] + } return config; }, }; diff --git a/examples/next-14/package-lock.json b/examples/next-14/package-lock.json index baa75ca..3310e33 100644 --- a/examples/next-14/package-lock.json +++ b/examples/next-14/package-lock.json @@ -8,7 +8,9 @@ "name": "next-14-demo", "version": "0.1.0", "dependencies": { - "next": "14.2.11", + "msnodesqlv8": "^4.2.1", + "next": "=14.2.15", + "nextjs-node-loader": "file:../..", "node-el-slugify": "^0.1.4-beta.4", "react": "^18", "react-dom": "^18", @@ -20,29 +22,33 @@ "@types/react-dom": "^18", "eslint": "^8", "eslint-config-next": "14.2.15", - "nextjs-node-loader": "file:../..", "typescript": "^5" } }, "../..": { - "version": "1.1.5", - "dev": true, + "version": "1.1.8", "license": "MIT", "dependencies": { - "loader-utils": "^2.0.3" + "loader-utils": "^3.0.0" }, "devDependencies": { - "@babel/cli": "^7.20.7", - "@babel/core": "^7.20.12", - "@babel/preset-env": "^7.22.20", + "@babel/cli": "^7.25.7", + "@babel/core": "^7.25.7", + "@babel/preset-env": "^7.25.7", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.12.0", + "@types/jest": "^29.5.13", "@webpack-contrib/eslint-config-webpack": "^3.0.0", "babel-jest": "^29.0.0", "cross-env": "^7.0.3", "eslint": "^9.12.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.31.0", + "eslint-plugin-prettier": "^5.1.3", + "fs-extra": "^11.2.0", "jest": "^29.0.0", "memfs": "^4.13.0", + "next": "^14.2.14", "prettier": "^3.3.3", "webpack": "^5.85.0" }, @@ -218,9 +224,9 @@ } }, "node_modules/@next/env": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.11.tgz", - "integrity": "sha512-HYsQRSIXwiNqvzzYThrBwq6RhXo3E0n8j8nQnAs8i4fCEo2Zf/3eS0IiRA8XnRg9Ha0YnpkyJZIZg1qEwemrHw==" + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.15.tgz", + "integrity": "sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==" }, "node_modules/@next/eslint-plugin-next": { "version": "14.2.15", @@ -232,9 +238,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.11.tgz", - "integrity": "sha512-eiY9u7wEJZWp/Pga07Qy3ZmNEfALmmSS1HtsJF3y1QEyaExu7boENz11fWqDmZ3uvcyAxCMhTrA1jfVxITQW8g==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.15.tgz", + "integrity": "sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==", "cpu": [ "arm64" ], @@ -247,9 +253,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.11.tgz", - "integrity": "sha512-lnB0zYCld4yE0IX3ANrVMmtAbziBb7MYekcmR6iE9bujmgERl6+FK+b0MBq0pl304lYe7zO4yxJus9H/Af8jbg==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.15.tgz", + "integrity": "sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==", "cpu": [ "x64" ], @@ -262,9 +268,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.11.tgz", - "integrity": "sha512-Ulo9TZVocYmUAtzvZ7FfldtwUoQY0+9z3BiXZCLSUwU2bp7GqHA7/bqrfsArDlUb2xeGwn3ZuBbKtNK8TR0A8w==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.15.tgz", + "integrity": "sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==", "cpu": [ "arm64" ], @@ -277,9 +283,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.11.tgz", - "integrity": "sha512-fH377DnKGyUnkWlmUpFF1T90m0dADBfK11dF8sOQkiELF9M+YwDRCGe8ZyDzvQcUd20Rr5U7vpZRrAxKwd3Rzg==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.15.tgz", + "integrity": "sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==", "cpu": [ "arm64" ], @@ -292,9 +298,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.11.tgz", - "integrity": "sha512-a0TH4ZZp4NS0LgXP/488kgvWelNpwfgGTUCDXVhPGH6pInb7yIYNgM4kmNWOxBFt+TIuOH6Pi9NnGG4XWFUyXQ==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.15.tgz", + "integrity": "sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==", "cpu": [ "x64" ], @@ -307,9 +313,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.11.tgz", - "integrity": "sha512-DYYZcO4Uir2gZxA4D2JcOAKVs8ZxbOFYPpXSVIgeoQbREbeEHxysVsg3nY4FrQy51e5opxt5mOHl/LzIyZBoKA==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.15.tgz", + "integrity": "sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==", "cpu": [ "x64" ], @@ -322,9 +328,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.11.tgz", - "integrity": "sha512-PwqHeKG3/kKfPpM6of1B9UJ+Er6ySUy59PeFu0Un0LBzJTRKKAg2V6J60Yqzp99m55mLa+YTbU6xj61ImTv9mg==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.15.tgz", + "integrity": "sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==", "cpu": [ "arm64" ], @@ -337,9 +343,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.11.tgz", - "integrity": "sha512-0U7PWMnOYIvM74GY6rbH6w7v+vNPDVH1gUhlwHpfInJnNe5LkmUZqhp7FNWeNa5wbVgRcRi1F1cyxp4dmeLLvA==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.15.tgz", + "integrity": "sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==", "cpu": [ "ia32" ], @@ -352,9 +358,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.11.tgz", - "integrity": "sha512-gQpS7mcgovWoaTG1FbS5/ojF7CGfql1Q0ZLsMrhcsi2Sr9HEqsUZ70MPJyaYBXbk6iEAP7UXMD9HC8KY1qNwvA==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.15.tgz", + "integrity": "sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==", "cpu": [ "x64" ], @@ -1122,9 +1128,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001614", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz", - "integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==", + "version": "1.0.30001669", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", + "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", "funding": [ { "type": "opencollective", @@ -3328,6 +3334,129 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/msnodesqlv8": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/msnodesqlv8/-/msnodesqlv8-4.2.1.tgz", + "integrity": "sha512-ezVHYnQnHEuNex3PcMslFxHHrJB7tyNqvh5IeMclfuE23lbxZ7NbbVuQUu6x2+eL82jTz5RKmlqPXQQXM74sjw==", + "hasInstallScript": true, + "os": [ + "win32", + "linux", + "darwin" + ], + "dependencies": { + "nan": "^2.19.0", + "node-abi": "^3.60.0", + "prebuild-install": "^7.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/msnodesqlv8/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/msnodesqlv8/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/msnodesqlv8/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/msnodesqlv8/node_modules/node-abi": { + "version": "3.68.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.68.0.tgz", + "integrity": "sha512-7vbj10trelExNjFSBm5kTvZXXa7pZyKWx9RCKIyqe6I9Ev3IzGpQoqBP3a+cOdxY+pWj6VkP28n/2wWysBHD/A==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/msnodesqlv8/node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/msnodesqlv8/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/msnodesqlv8/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/nan": { "version": "2.22.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", @@ -3362,11 +3491,11 @@ "dev": true }, "node_modules/next": { - "version": "14.2.11", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.11.tgz", - "integrity": "sha512-8MDFqHBhdmR2wdfaWc8+lW3A/hppFe1ggQ9vgIu/g2/2QEMYJrPoQP6b+VNk56gIug/bStysAmrpUKtj3XN8Bw==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.15.tgz", + "integrity": "sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==", "dependencies": { - "@next/env": "14.2.11", + "@next/env": "14.2.15", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -3381,15 +3510,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.11", - "@next/swc-darwin-x64": "14.2.11", - "@next/swc-linux-arm64-gnu": "14.2.11", - "@next/swc-linux-arm64-musl": "14.2.11", - "@next/swc-linux-x64-gnu": "14.2.11", - "@next/swc-linux-x64-musl": "14.2.11", - "@next/swc-win32-arm64-msvc": "14.2.11", - "@next/swc-win32-ia32-msvc": "14.2.11", - "@next/swc-win32-x64-msvc": "14.2.11" + "@next/swc-darwin-arm64": "14.2.15", + "@next/swc-darwin-x64": "14.2.15", + "@next/swc-linux-arm64-gnu": "14.2.15", + "@next/swc-linux-arm64-musl": "14.2.15", + "@next/swc-linux-x64-gnu": "14.2.15", + "@next/swc-linux-x64-musl": "14.2.15", + "@next/swc-win32-arm64-msvc": "14.2.15", + "@next/swc-win32-ia32-msvc": "14.2.15", + "@next/swc-win32-x64-msvc": "14.2.15" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -3699,9 +3828,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.1", diff --git a/examples/next-14/package.json b/examples/next-14/package.json index e623f1d..40e5cab 100644 --- a/examples/next-14/package.json +++ b/examples/next-14/package.json @@ -9,7 +9,9 @@ "lint": "next lint" }, "dependencies": { - "next": "14.2.11", + "msnodesqlv8": "^4.2.1", + "next": "=14.2.15", + "nextjs-node-loader": "file:../..", "node-el-slugify": "^0.1.4-beta.4", "react": "^18", "react-dom": "^18", @@ -21,7 +23,6 @@ "@types/react-dom": "^18", "eslint": "^8", "eslint-config-next": "14.2.15", - "nextjs-node-loader": "file:../..", "typescript": "^5" } } diff --git a/package-lock.json b/package-lock.json index 089a9d6..fe262ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "fs-extra": "^11.2.0", "jest": "^29.0.0", "memfs": "^4.13.0", + "next": "^14.2.14", "prettier": "^3.3.3", "webpack": "^5.85.0" }, @@ -2761,6 +2762,156 @@ "tslib": "2" } }, + "node_modules/@next/env": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.14.tgz", + "integrity": "sha512-/0hWQfiaD5//LvGNgc8PjvyqV50vGK0cADYzaoOOGN8fxzBn3iAiaq3S0tCRnFBldq0LVveLcxCTi41ZoYgAgg==", + "dev": true + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.14.tgz", + "integrity": "sha512-bsxbSAUodM1cjYeA4o6y7sp9wslvwjSkWw57t8DtC8Zig8aG8V6r+Yc05/9mDzLKcybb6EN85k1rJDnMKBd9Gw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.14.tgz", + "integrity": "sha512-cC9/I+0+SK5L1k9J8CInahduTVWGMXhQoXFeNvF0uNs3Bt1Ub0Azb8JzTU9vNCr0hnaMqiWu/Z0S1hfKc3+dww==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.14.tgz", + "integrity": "sha512-RMLOdA2NU4O7w1PQ3Z9ft3PxD6Htl4uB2TJpocm+4jcllHySPkFaUIFacQ3Jekcg6w+LBaFvjSPthZHiPmiAUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.14.tgz", + "integrity": "sha512-WgLOA4hT9EIP7jhlkPnvz49iSOMdZgDJVvbpb8WWzJv5wBD07M2wdJXLkDYIpZmCFfo/wPqFsFR4JS4V9KkQ2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.14.tgz", + "integrity": "sha512-lbn7svjUps1kmCettV/R9oAvEW+eUI0lo0LJNFOXoQM5NGNxloAyFRNByYeZKL3+1bF5YE0h0irIJfzXBq9Y6w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.14.tgz", + "integrity": "sha512-7TcQCvLQ/hKfQRgjxMN4TZ2BRB0P7HwrGAYL+p+m3u3XcKTraUFerVbV3jkNZNwDeQDa8zdxkKkw2els/S5onQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.14.tgz", + "integrity": "sha512-8i0Ou5XjTLEje0oj0JiI0Xo9L/93ghFtAUYZ24jARSeTMXLUx8yFIdhS55mTExq5Tj4/dC2fJuaT4e3ySvXU1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.14.tgz", + "integrity": "sha512-2u2XcSaDEOj+96eXpyjHjtVPLhkAFw2nlaz83EPeuK4obF+HmtDJHqgR1dZB7Gb6V/d55FL26/lYVd0TwMgcOQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.14.tgz", + "integrity": "sha512-MZom+OvZ1NZxuRovKt1ApevjiUJTcU2PmdJKL66xUPaJeRywnbGGRWUlaAOwunD6dX+pm83vj979NTC8QXjGWg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "dev": true, @@ -2804,6 +2955,22 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "dev": true, + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "dev": true, @@ -3610,6 +3777,18 @@ "dev": true, "license": "MIT" }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/call-bind": { "version": "1.0.7", "dev": true, @@ -3728,6 +3907,12 @@ "dev": true, "license": "MIT" }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "dev": true + }, "node_modules/co": { "version": "4.6.0", "dev": true, @@ -7349,6 +7534,19 @@ "dev": true, "license": "MIT" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "dev": true, @@ -7481,6 +7679,24 @@ "dev": true, "license": "MIT" }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -7491,6 +7707,56 @@ "dev": true, "license": "MIT" }, + "node_modules/next": { + "version": "14.2.14", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.14.tgz", + "integrity": "sha512-Q1coZG17MW0Ly5x76shJ4dkC23woLAhhnDnw+DfTc7EpZSGuWrlsZ3bZaO8t6u1Yu8FVfhkqJE+U8GC7E0GLPQ==", + "dev": true, + "dependencies": { + "@next/env": "14.2.14", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.14", + "@next/swc-darwin-x64": "14.2.14", + "@next/swc-linux-arm64-gnu": "14.2.14", + "@next/swc-linux-arm64-musl": "14.2.14", + "@next/swc-linux-x64-gnu": "14.2.14", + "@next/swc-linux-x64-musl": "14.2.14", + "@next/swc-win32-arm64-msvc": "14.2.14", + "@next/swc-win32-ia32-msvc": "14.2.14", + "@next/swc-win32-x64-msvc": "14.2.14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, "node_modules/node-int64": { "version": "0.4.0", "dev": true, @@ -7834,6 +8100,34 @@ "node": ">= 0.4" } }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "dev": true, @@ -7934,6 +8228,33 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, "node_modules/react-is": { "version": "18.2.0", "dev": true, @@ -8126,6 +8447,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/schema-utils": { "version": "3.3.0", "dev": true, @@ -8251,6 +8582,15 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "dev": true, @@ -8284,6 +8624,15 @@ "node": ">=8" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "dev": true, @@ -8393,6 +8742,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "dev": true, + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/supports-color": { "version": "5.5.0", "dev": true, diff --git a/package.json b/package.json index f4d6658..810ce2d 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "fs-extra": "^11.2.0", "jest": "^29.0.0", "memfs": "^4.13.0", + "next": "^14.2.14", "prettier": "^3.3.3", "webpack": "^5.85.0" }, diff --git a/src/index.js b/src/index.js index ad954eb..8b51432 100644 --- a/src/index.js +++ b/src/index.js @@ -14,18 +14,14 @@ export default function loader(content) { }); emitFile(name, content); - - return ` -try { - process.dlopen(module, ${JSON.stringify( - outputPath || _compiler.options.output.path - )} + require("path").sep + ${isWebpackPathIncluded ? '__webpack_public_path__' : '""'} + ${JSON.stringify(name)}${ - typeof flags !== 'undefined' ? `, ${JSON.stringify(options.flags)}` : '' - }); -} catch (error) { - throw new Error('nextjs-node-loader:\\n' + error); -} -`; + const targetOutputPath = outputPath || _compiler.options.output.path; + const webpackPublicPath = isWebpackPathIncluded ? '__webpack_public_path__' : '""'; + const cleanedTargetOutputPath = targetOutputPath.replace(/\\/g, '/'); + const moduleFlags = typeof flags !== 'undefined' ? `, ${options.flags}` : ''; + const loaderScript = ` + process.dlopen(module, require('path').join("${cleanedTargetOutputPath}", ${webpackPublicPath}, "${name}")${moduleFlags});`; + // console.log(loaderScript); + return loaderScript; } export const raw = true; diff --git a/test/inspectnext.js b/test/inspectnext.js new file mode 100644 index 0000000..70bb6a7 --- /dev/null +++ b/test/inspectnext.js @@ -0,0 +1,25 @@ +const path = require('path'); +const fs = require('fs'); + +const next = require('next'); + +// Create a custom build script to inspect Webpack configuration +async function inspectWebpackConfig() { + const app = next({ + dev: false, + dir: '.', + }); + + await app.prepare(); + + const config = await app.server.getWebpackConfig(); + console.log('Webpack Configuration:', config); + + fs.writeFileSync(path.join(__dirname, 'webpack-config.json'), JSON.stringify(config, null, 2)); + + console.log('Webpack config saved to webpack-config.json'); +} + +inspectWebpackConfig().catch((err) => { + console.error('Error during Webpack inspection:', err); +}); diff --git a/test/loader.test.js b/test/loader.test.js new file mode 100644 index 0000000..8d965d5 --- /dev/null +++ b/test/loader.test.js @@ -0,0 +1,59 @@ +const fs = require('fs'); + +const loader = require('../src/index'); + +jest.mock('fs'); +jest.mock('loader-utils', () => { + return { + interpolateName: jest.fn(), + }; +}); + +describe('Loader', () => { + let context; + + beforeEach(() => { + context = { + rootContext: '/project/root', + _compiler: { + options: { + output: { + path: '/dist', + }, + }, + }, + emitFile: jest.fn(), + getOptions: jest.fn(), + }; + }); + + it('should return the correct loader output string', () => { + const { interpolateName } = require('loader-utils'); + interpolateName.mockReturnValue('file.js'); + + fs.existsSync.mockReturnValue(true); + context.getOptions.mockReturnValue({ + // eslint-disable-next-line no-undefined + flags: undefined, + // eslint-disable-next-line no-undefined + outputPath: undefined, + includeWebpackPublicPath: true, + }); + + const content = Buffer.from('console.log("test content");'); + + const result = loader.default.call(context, content); + + const expectedOutput = ` +try { + const pathToOpen = require('path').join("/dist", "/", __webpack_public_path__, "file.js"); + process.dlopen(module, pathToOpen, undefined); +} catch (error) { + throw new Error('nextjs-node-loader:\\n' + error); +} +`; + + // Test: Verify the output string matches + expect(result.trim()).toEqual(expectedOutput.trim()); + }); +});