-
Notifications
You must be signed in to change notification settings - Fork 1k
Extending Webpack
As part of the SPFX tooling, we have tried to stick closely to using common open source tooling. We've wrapped some of it up into a build pipeline that we use internally, and have [published it to GitHub] (https://github.com/Microsoft/web-build-tools). One common request that has been made is to extend the Webpack step of the build.
What is a Webpack loader?
There are many cases where one would like to import and utilize a non-JavaScript resource during development, typically this is done with images or templates. A Webpack loader will convert the resource into something that can be utilized by your JS application. For example, a Markdown template may be compiled and converted to a text string, while a image resource may be converted to Base64 or the require()
statement might return a path to that particular file.
There are a number of useful loaders, several of which are already used by the standard SPFx webpack configuration:
html-loader
json-loader
loader-load-themed-styles
Writing loaders is a straightforward process which is documented here.
As an example, let's use the markdown-loader package. It's a loader which allows you to reference an .md file and output it as HTML.
Let's reference markdown-loader in our project.
npm i --save markdown-loader
In the documentation of markdown-loader, it shows how to extend the Webpack configuration.
{
module: {
loaders: [
{ test: /\.md$/, loader: "html!markdown" }
]
}
}
Here's how to do that in the SPFX toolchain:
Edit the gulpfile.js
and add the following code right before build.initialize(gulp);
:
build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) => {
generatedConfiguration.module.loaders.push([
{ test: /\.md$/, loader: "html!markdown" }
]);
return generatedConfiguration;
}
});
Notice that we simply push the loader config onto the list of existing loaders in the toolchain. It's important to ensure that your additionalConfiguration
function ends with the return generatedConfiguration
line, as this function allows you to completely replace the Webpack configuration. Completely replacing the Webpack configuration is not recommended except in very advanced scenarios, however.
Create a file (say readme.md
) in your src/webparts/helloworld
folder (or whatever your folder name is) with some Markdown in it.
Next, add the following require()
line at the top of you HelloWorldWebPart.ts
file after your imports:
const html : string = require("../../../src/webparts/helloworld/readme.md");
Then reference it in your render method:
public render(): void {
this.domElement.innerHTML = html;
}
run gulp serve
and see your new part in action.
So that require statement is pretty ugly. Webpack will look in the lib
folder for the file, but by default .md
files don't get copied to the lib
folder, meaning we need to create a rather ugly relative path. There is a better way though.
Create a file copy-static-assets.json
in the config
directory to tell the build system to copy some additional files from src
to lib
. By default, this build task copies files with extensions that the default SPFx Webpack configuration understands (like png
and json
), so we just need to tell it to also copy md
files.
{
"includeExtensions": [
"md"
]
}
This says "copy everything in the source directory with a .md extension to the lib directory, and keep the same directory structure."
Next, clean up your require statement to look like:
const html: string = require("./readme.md");
ctrl+c
any running gulp serve
task and rebuild (gulp serve
) your project again. You should see a readme.md
file in your lib directory under webparts\helloworld
.
-
Getting Started