Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
babel-plugin-run-on-server
Advanced tools
Babel plugin that compiles id mappings for run-on-server.
This is the companion babel plugin for run-on-server.
It does two things:
require
with eval("require")
within runOnServer
callsSee the documentation below for an explanation of each functionality and the rationale behind it.
require
with eval("require")
If you try to compile this using webpack:
runOnServer(
(code) => {
const prettier = require("prettier");
return prettier.format(code);
},
[code]
);
Then webpack will include the "prettier" module in your clientside code.
Since you're only using it serverside, this is unnecesary.
If eval("require")
is used instead of require
, then webpack won't include the module in your clientside code:
runOnServer(
(code) => {
const prettier = eval("require")("prettier");
return prettier.format(code);
},
[code]
);
This plugin can replace require
with eval("require")
for you.
run-on-server
lets you run arbitrary code written on the client (browser, node) on the server (node). It can be great for prototyping, but it's insecure out of the box because its server will eval any JavaScript code you throw at it. That makes it unsuitable for production use because any deployed server would be wide open for attackers to run code on.
This babel plugin solves that issue by making run-on-server/server
refuse to run any code except for the code that appeared in your source.
Here's how it works:
runOnServer
runOnServer
with an autogenerated IDrunOnServer
.This id mappings file can then be fed into run-on-server/server
, which configures the server so that it only runs code appearing in the id mappings file.
It might be easier to visualize with an example:
Normally, run-on-server/client
code looks like this:
// src/client.js
import createClient from "run-on-server/client";
const runOnServer = createClient("http://localhost:3001");
runOnServer(() => process.version).then((version) => console.log(version));
The babel plugin compiles it to this:
// dist/client.js
import createClient from "run-on-server/client";
const runOnServer = createClient("http://localhost:3001");
runOnServer({
id: "073f3eb62747a1dbb64a5527c79224ad",
}).then((version) => console.log(version));
And the babel plugin also creates an id mappings file with this content:
// run-on-server-id-mappings.js
/*
This file was generated by the run-on-server babel plugin. It should not
be edited by hand.
*/ module.exports = {
"073f3eb62747a1dbb64a5527c79224ad": () => process.version,
};
Note that the autogenerated id (073f3eb62747a1dbb64a5527c79224ad
) is the same in the code and the id mappings file.
Now, if you feed the id mappings into run-on-server/server
:
const createServer = require("run-on-server/server");
const server = createServer({
idMappings: require("./run-on-server-id-mappings"),
});
server.listen(3001, () => {
console.log("Server is listening on port 3001");
});
Then the server will be locked down so that it can only ever run () => process.version
.
By leveraging this babel plugin, run-on-server
becomes feasible for use in production-facing libraries and applications.
Install the package babel-plugin-run-on-server
:
$ npm install --save-dev babel-plugin-run-on-server
# OR
$ yarn add --dev babel-plugin-run-on-server
Add it to your .babelrc
:
{
"plugins": ["run-on-server"]
}
By default, the plugin doesn't do anything. You need to enable each feature by passing options to the plugin in your .babelrc
:
{
"plugins": [
[
"run-on-server",
{
"evalRequire": {
"enabled": true
},
"idMappings": {
"enabled": true,
"outputPath": "./server/idMappings.js"
}
}
]
]
}
evalRequire.enabled
Whether to compile require
into eval("require")
within runOnServer
calls. Defaults to false
.
idMappings.enabled
Whether to compile id mappings and replace the code in runOnServer
calls with id mappings. Defaults to false
.
idMappings.outputPath
By default, the id mappings file will be written to run-on-server-id-mappings.js
in whatever directory you run babel in. You can configure it by setting the idMappings.outputPath
option.
The plugin never removes entries from the id mappings file, it only adds them. This means that your id mappings file will grow over time and contain entries for code you no longer have. To clean the entries up, remove the id mappings file and re-run babel. It's best practice to clear out all entries before releasing a new production-facing build.
If you are building content from a src
directory into a dist
directory, my recommendation is to output the id mappings file into dist
, and then clear the contents of dist
before running each build (as part of your build script).
The outputPath in .babelrc
is resolved relative to where you run babel
(process.cwd()
). This usually works, but if your id mappings file is getting put in the wrong place, you might want to use this workaround to give an absolute path to the plugin:
.babelrc
to have this content:{
"presets": ["./.babelrc.js"]
}
.babelrc.js
in the same directory as .babelrc
, and make it export a config object containing everything your .babelrc
had in it before:module.exports = {
plugins: [
[
"run-on-server",
{
idMappings: {
enabled: true,
outputPath: "./server/idMappings.js",
},
},
],
],
};
path
module and wrap your outputPath
like so:const path = require("path");
module.exports = {
plugins: [
[
"run-on-server",
{
idMappings: {
enabled: true,
outputPath: path.resolve(__dirname, "./server/idMappings.js"),
},
},
],
],
};
Note: If you are using Babel 7, you don't need to do the
"presets": ["./.babelrc.js"]
.babelrc
workaround, as.babelrc.js
will be loaded by babel without any additional config.
FAQs
Babel plugin that compiles id mappings for run-on-server.
We found that babel-plugin-run-on-server demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.