Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Using Truffle and Webpack (beta)

Tim Coulter edited this page Oct 3, 2016 · 7 revisions

WARNING: This page is outdated

This page is outdated and no longer maintained. A better, more usable way to integrate Truffle and Webpack can be found on Truffle's new dedicated website. The Truffle website contains tutorials, news and help information, as well as links to Truffle's Gitter chat room. Don't hesitate to reach out with any questions.

The old document, for history's sake

Note: This document assumes you've started with a project that was originally created using truffle init and relied on the default Truffle builder.

1. Get the latest Truffle

Right now, you need Truffle from source:

$ npm uninstall -g truffle
$ cd <your workspace>
$ git clone https://github.com/ConsenSys/truffle.git
$ cd truffle
$ npm install -g .

2. Install webpack

$ npm install -g webpack

3. Navigate to your project and install dependencies

Here, we assume you're using React too.

$ cd <your workspace>/<your project>
$ npm install babel-core babel-loader babel-preset-es2015 babel-preset-react sass-loader style-loader node-sass json-loader webpack extract-text-webpack-plugin copy-webpack-plugin ether-pudding web3 bluebird --save

Then because we have a special ether-pudding, link it too:

$ cd <your workspace>/<your project>
$ npm link ether-pudding

4. Create a .babelrc:

$ touch <yourworkspace>/<your project>/.babelrc

Fill it with this:

{
  "ignore": ["*.min.js"],
  "compact": false,
  "presets": ["es2015", "react"]
}

5. Create a webpack.config.js file:

$ touch <yourworkspace>/<your project>/webpack.config.js

And fill it with this:

var fs = require("fs");
var path = require('path');
var webpack = require("webpack");
var CopyWebpackPlugin = require('copy-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");

var environment = process.env.NODE_ENV || "development";

var provided = {
  "Web3": "web3",
  "Pudding": "ether-pudding",
  "Promise": "bluebird"
};

// Get all the compiled contracts for our environment.
var contracts_directory = path.join("./", "environments", environment, "contracts");
fs.readdirSync("./environments/" + environment + "/contracts").forEach(function(file) {
  if (path.basename(file).indexOf(".sol.js")) {
    provided[path.basename(file, ".sol.js")] = path.resolve(contracts_directory + "/" + file);
  }
});

module.exports = {
  entry: './app/javascripts/app.js',
  output: {
    path: "./environments/" + environment + "/build",
    filename: 'app.js'
  },
  module: {
    loaders: [
      { test: /\.(js|jsx|es6)$/, exclude: /node_modules/, loader: "babel-loader"},
      { test: /\.scss$/i, loader: ExtractTextPlugin.extract(["css", "sass"])},
      { test: /\.json$/i, loader: "json"}
    ]
  },
  plugins: [
    new webpack.DefinePlugin({
        ENV: '"' + process.env.NODE_ENV + '"',
        WEB3_PROVIDER_LOCATION: '"' + process.env.WEB3_PROVIDER_LOCATION + '"'
    }),
    new webpack.ProvidePlugin(provided),
    new CopyWebpackPlugin([
      { from: './app/index.html', to: "index.html" },
      { from: './app/images', to: "images" },
    ]),
    new ExtractTextPlugin("app.css")
  ],
  resolve: { fallback: path.join(__dirname, "node_modules") },
  resolveLoader: { fallback: path.join(__dirname, "node_modules") }
};

6. Change your entry in webpack.config.js

Open up wepback.config.js, and change the entry configuration so that it points to the main file of your app. This file is responsible for import'ing/require'ing all other dependencies.

7. Change the configuration of webpack.config.js to match your file structure.

Notice that in webpack.config.js, we use the CopyWebpackPlugin to move the index.html file and images directory over during the build process. If you have other/different files and folders you need to copy, change this configuration to match your project.

8. Remove dependencies from truffle.js, and import instead.

Find your truffle.js file and locate the build keyword. All the files and folders you list there for app.js need to be import'ed or require'ed instead, where needed within your application. Also -- and this is odd, but it's a "webpack-ism" -- you have to import your CSS as well. Here, we're importing a .scss file which uses sass imports to include the rest of our CSS. We only import the CSS file once in our entry JS file; the resulting CSS will be pulled out into its own file later on in the build process.

import {} from "../stylesheets/app.scss";

import NavBar from "./navbar.jsx";
import Footer from "./footer.jsx";
import FrontPage from "./frontpage.jsx";
import DappPage from "./dapppage.jsx";
...

9. Edit the build keyword in truffle.js

We're using webpack. So let's completely replace the value of the build keyword in truffle.js with a single string. This string represents the command that will be run by Truffle to initiate your build process. Your truffle.js should look like this:

{
  "build": "webpack",
  "deploy": [
    ...
  ],
  "rpc": {
    ...
  }
};

10. Run the build!

$ truffle build

This will run your build process, which just runs webpack behind the scenes. Let me know if it works!