Since webpack creates JavaScript bundles and the liferay-npm-bundler targets AMD loader, webpack’s loaders aren’t compatible with the liferay-npm-bundler. So, if you want to use a loader that isn’t available by default, you must create a custom loader.
A loader, in terms of the liferay-npm-bundler, is defined as an npm package that has a main module which exports a default function with this signature:
function(context, options){
}
The arguments are defined as follows:
context
: an object containing these fields:
content
: a string with the contents of the processed file (the main input of the loader)
filepath
: the project-relative path to the file to process with the loader
extraArtifacts
: an object with project-relative paths as keys and strings as values of properties that may be used to output extra files along with the one being processed (for example, you can use it to generate source maps).
log
: a logger that writes execution information to the bundler’s report file (see thePluginLogger
class for information on its structure and API).
options
: an object taken from the options
field of the loader’s
configuration (See Understanding liferay-npm-bundler’s loaders and rules
for more information).
Follow these steps to write a new loader. These steps use the Babel loader as an example:
-
If your loader requires configuration, like Babel, you may define a rule configuration like the one shown below so you can specify options for the loader:
{ "rules": [ { "test": "\\.js$", "exclude": "node_modules", "use": [ { "loader": "babel-loader", "options": { "presets": ["env", "react"] } } ] } ] }
-
Create an
index.js
file and write a function that takes the input content, passes it through the loader, and writes the result and the source map file to the output folder. The loader function below takes the passed content (JS files), run it through babel, and writes the result and source map to the default/build/
output folder:export default function(context, options) { // Get input parameters const { content, filePath, log, sourceMap } = context; // Run babel on content const result = babel.transform(content, options); // Create an extra .map file with source map next to source .js file context.extraArtifacts[`${filePath}.map`] = JSON.stringify(result.map); // Tell the user what we have done log.info("babel-loader", "Transpiled file"); // Return the modified content return result.code; }
-
Place the
index.js
file in an npm package and publish it. -
Include the npm package you just created as a
devDependency
in the project’spackage.json
:"devDependencies": { "liferay-npm-bundler": "2.12.0", "liferay-npm-build-support": "2.12.0", "liferay-npm-bundler-loader-babel-loader": "2.12.0", ... }
-
Configure the loader’s name in the
rules
section of the project’s.npmbundlerrc
file:{ "sources": ["src"], ... "rules": [ { "test": "\\.js$", "exclude": "node_modules", "use": [ { "loader": "babel-loader", "options": { "presets": ["env", "react"] } } ] } ], ... }