What is @vercel/webpack-asset-relocator-loader?
@vercel/webpack-asset-relocator-loader is a Webpack loader that helps in relocating assets referenced in JavaScript files. It is particularly useful for bundling Node.js applications where assets need to be moved to a specific location in the output directory.
What are @vercel/webpack-asset-relocator-loader's main functionalities?
Relocate Assets
This feature allows you to relocate assets referenced in JavaScript files to a specified directory in the output. The code sample demonstrates how to configure the loader to move assets to the 'assets' directory.
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: '@vercel/webpack-asset-relocator-loader',
options: {
outputAssetBase: 'assets',
},
},
},
],
},
};
Inline Asset Handling
This feature allows you to inline assets directly into the JavaScript bundle. The code sample shows how to configure the loader to inline assets.
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: '@vercel/webpack-asset-relocator-loader',
options: {
inline: true,
},
},
},
],
},
};
Custom Asset Extensions
This feature allows you to specify custom extensions for assets that need to be relocated. The code sample demonstrates how to configure the loader to handle '.wasm' and '.node' files.
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: '@vercel/webpack-asset-relocator-loader',
options: {
extensions: ['.wasm', '.node'],
},
},
},
],
},
};
Other packages similar to @vercel/webpack-asset-relocator-loader
file-loader
file-loader is a Webpack loader that resolves import/require() on a file into a url and emits the file into the output directory. It is similar to @vercel/webpack-asset-relocator-loader in that it handles asset relocation, but it does not provide the same level of integration with Node.js applications.
url-loader
url-loader works like file-loader but can return a DataURL if the file is smaller than a byte limit. It is useful for inlining small assets into the JavaScript bundle, similar to the inline feature of @vercel/webpack-asset-relocator-loader.
copy-webpack-plugin
copy-webpack-plugin copies individual files or entire directories to the build directory. While it does not directly handle asset references in JavaScript files, it can be used in conjunction with other loaders to achieve similar results to @vercel/webpack-asset-relocator-loader.
Asset Relocator Loader for Webpack
Asset relocation loader used in ncc for performing Node.js builds while emitting and relocating any asset references.
Usage
Installation
npm i -g @vercel/webpack-asset-relocator-loader
Usage
Add this loader as a Webpack plugin for any JS files.
Any .node
files included will also support binary relocation.
{
target: "node",
output: {
libraryTarget: "commonjs2"
},
module: {
rules: [
{
test: /\.(m?js|node)$/,
parser: { amd: false },
use: {
loader: '@vercel/webpack-asset-relocator-loader',
options: {
outputAssetBase: 'assets',
filterAssetBase: process.cwd(),
emitDirnameAll: false,
emitFilterAssetBaseAll: false,
customEmit: (path, { id, isRequire }) => false | '"./custom-replacement"',
existingAssetNames: [],
wrapperCompatibility: false,
production: true,
cwd: process.cwd(),
debugLog: false,
}
}
}
]
}
}
Assets will be emitted using emitAsset
, with their references updated in the code by the loader to the new output location.
Asset Permissions and Symlinks
Asset symlinks and permissions are maintained in the loader, but aren't passed to Webpack as emit
doesn't support these.
This information can be obtained from the loader through the API calls getAssetMeta()
and getSymlinks()
:
const relocateLoader = require('webpack-asset-relocator-loader');
webpack({...}).run((err, stats) => {
const assetMeta = relocateLoader.getAssetMeta();
const symlinks = relocateLoader.getSymlinks();
});
They will always contain the most recent build state.
Caching
When using Webpack 5 caching, asset permissions need to be maintained through their own cache, and the public path needs to be injected into the build.
To ensure these cases work out, make sure to run initAssetCache
in the build, with the options.outputAssetBase
argument:
const relocateLoader = require('webpack-asset-relocator-loader');
webpack({
plugins: [
{
apply(compiler) {
compiler.hooks.compilation.tap("webpack-asset-relocator-loader", compilation => {
relocateLoader.initAssetCache(compilation, outputAssetBase);
});
}
}
]
});
How it Works
Asset Relocation
Assets are detected using static analysis of code, based on very specific triggers designed for common Node.js workflows to provide build support for a very high (but not perfect) level of compatibility with existing Node.js libraries.
process.cwd()
, __filename
, __dirname
, path.*()
, require.resolve
are all statically analyzed when possible.- File emissions for exact asset paths
- Whole directory asset emissions for exact directory paths
- Wildcard asset emissions for variable path expressions
When an asset is emitted, the pure expression referencing the asset path is replaced with a new expression to the relocated asset and the asset emitted. In the case of wildcard emission, the dynamic parts of the expression are maintained.
Binary Relocation
Node binary loading conventions cover the following triggers for binary relocations:
require('bindings')(...)
nbind.init(..)
node-pre-gyp
include patterns
Any shared libraries loaded by these binaries will also be emitted as well.
Node.js Compatibility Features
In addition to asset relocation, this loader also provides a couple
of compatibility features for Webpack Node.js builds as part of its analysis.
These include:
require.main === module
checks are retained for the entry point being built.options.wrapperCompatibility
: Automatically handles common AMD / Browserify wrappers to ensure they are properly built by Webpack. See the utils/wrappers.js
file for the exact transformations currently provided.require.resolve
support in the target environment, while also supporting emission in the build environment.- Dynamic
require
statements are analyzed to exact paths wherever possible, and when not possible to analyze, turned into dynamic requires in the target environment.