Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Merge pull request #54 from eisberg-labs/fix-loader
Browse files Browse the repository at this point in the history
fix: update readme and example
  • Loading branch information
amarjanica authored Oct 22, 2024
2 parents ebb4220 + 5685397 commit 26bf469
Show file tree
Hide file tree
Showing 12 changed files with 807 additions and 147 deletions.
154 changes: 95 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)
6 changes: 6 additions & 0 deletions examples/next-14/app/api/msnodesqlv8/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import msnodesql from 'msnodesqlv8';

export async function GET() {
console.log(msnodesql)
return Response.json({'status': 'ok'});
}
1 change: 0 additions & 1 deletion examples/next-14/app/api/slugify/[slug]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ export async function GET(
{ params }: { params: { slug: string } }
) {
const slug = slugifier.slugify(params.slug);

return Response.json({message: slug});
}
41 changes: 41 additions & 0 deletions examples/next-14/inspectnext.js
Original file line number Diff line number Diff line change
@@ -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();
27 changes: 11 additions & 16 deletions examples/next-14/next.config.mjs
Original file line number Diff line number Diff line change
@@ -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;
},
};
Expand Down
Loading

0 comments on commit 26bf469

Please sign in to comment.