Skip to main content

Using webpack

Intermediate
Tutorial

Overview

Webpack is a popular and highly configurable module bundler for JavaScript-based applications. New projects created with dfx new that choose to create a default JavaScript frontend include a default webpack.config.js file that makes it easy to add specific modules such as react and markdown.

Entry and output configuration

In many cases, you can use the default webpack.config.js file as is, without any modification, or you can add plugins, modules, and other custom configurations to suit your needs. The specific changes you make to the webpack.config.js configuration largely depends on the other tools and frameworks you want to use.

For example, if you have experimented with the using the default frontend canister or using CSS to style frontends tutorials, you might have modified the following section to work with React JavaScript:

module: {
  rules: [
    { test: /\.(ts|tsx|jsx)$/, loader: "ts-loader" },
    { test: /\.css$/, use: ['style-loader','css-loader'] }
  ]
}

If your application does not use dfx to run your build script, you can provide the variables yourself. For example:

export DFX_NETWORK=ic 
export NODE_ENV=production
export HELLO_CANISTER_ID=j2o3j-fiaaa-aaaab-qbifa-cai
npm run build

Ensuring Node.js is available in a project

Because projects rely on webpack to provide the framework for the default frontend, you must have Node.js 16.0.0 or newer installed in your development environment and accessible in the project directory.

  • If you want to develop your project without using the default webpack configuration and canister aliases, you can remove the frontend canister from the dfx.json file or build your project using a specific canister name. For example, you can choose to build only the hello program's backend canister without building the frontend assets by running the following command:
dfx build hello_backend
  • If you are using the default webpack configuration and running dfx build fails, you should try running npm install in the project directory and then re-running dfx build.

  • If running npm install in the project directory doesn’t fix the issue, you should check the configuration of the webpack.config.js file for syntax errors.

Using other bundlers

You may want to use a bundler other than webpack. Per-bundler instructions are not ready yet, but if you are familiar with your bundler, the following steps should get you going:

  • Step 1: Remove the copy:types, prestart, and prebuild scripts from package.json.

  • Step 2: Run dfx deploy to generate the local bindings for your canisters.

  • Step 3: Copy the generated bindings to a directory where you would like to keep them.

  • Step 4: Modify declarations/<canister_name>/index.js and replace process.env.<CANISTER_NAME>_CANISTER_ID with the equivalent pattern for environment variables for your bundler.

Alternately, hardcode the canister ID if that is your preferred workflow.

  • Step 5: Commit the declarations and import them in your codebase.

Deploying a frontend canister without building frontend dependencies

If you'd like to deploy a frontend asset canister without building the node or npm dependency packages, you can manually download the Wasm module dfx uses for its default frontend canister and install the canister manually.

  • Step 1: Download dfx's asset canister's Wasm module.

wget https://github.com/dfinity/sdk/raw/0.15.2/src/distributed/assetstorage.wasm.gzand
  • Step 2: Install the canister.

dfx canister install <id instead of name> --wasm assetstorage.wasm.gz

Using the canister ID, the canister will not sync automatically. If you want the canister to sync according to the configuration in dfx.json, then use the canister name instead of the canister ID:

dfx canister install frontend_canister --wasm assetstorage.wasm.gz

To sync assets to the canister manually, you can use icx-asset sync, but this package must be installed with Rust: cargo install icx-asset.

Webpack dev server

Starting with dfx v0.7.7, the SDK now provides you with webpack-dev-server in the dfx new starter.

The webpack development server, webpack-dev-server, provides in-memory access to the webpack assets, enabling you to make changes and see them reflected in the browser right away using live reloading.

  • Step 1: Create a new project and navigate  into your project directory.

  • Step 2: Start the replica locally, if necessary, with the dfx start --clean --background command.

Then, deploy your dapp as you normally would by running the dfx deploy command.

  • Step 3: Start the webpack development server by running the following command:

npm start
  • Step 4: Open a web browser and navigate to the asset canister for your application using the URL returned in the command line. For example, this might be:

http://localhost:3000
  • Step 5: Open a new terminal window or tab and navigate to your project directory.

  • Step 6: Open the src/hello_frontend/src/index.js file for your project in a code editor and make changes to the content.

For example, you might add an element to the page using JavaScript:

document.body.onload = addElement;

function addElement () {
 // Create a new div element
 const newDiv = document.createElement("div");

 // Give it some content
 const newContent = document.createTextNode("Test live page reloading!");

 // Add the text node to the newly created div
 newDiv.appendChild(newContent);

 // Add the newly created element and its content into the DOM
 const currentDiv = document.getElementById("div1");
 document.body.insertBefore(newDiv, currentDiv);
}
  • Step 7: Save your changes to the index.js file.

  • Step 8: Refresh the browser or wait for it to refresh on its own to see your change.

When you are done working on the frontend for your project, you can stop the webpack development server by pressing Control-C.