Chad
Chad

Reputation: 2071

Preserving folder structure in output directory with webpack

I have the following folder structure:

/index.html
/app/index.tsx

After bundling with webpack, I would like to have the following ouput directory with the bundle.js injected into the index.html

/dist/index.html
/dist/app/bundle.js
/dist/app/bundle.js.map

I have the following webpack configuration

var webpack = require("webpack")
var HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = [
    {
        entry: "./app/index",
        output: {
            path: "./dist/app",
            filename: "bundle.js"
        },
        devtool: "source-map",
        resolve: {
            extensions: ["", ".tsx", ".ts", ".js"]
        },
        plugins: [
            new webpack.optimize.UglifyJsPlugin(),
            new HtmlWebpackPlugin({
                "filename": "./index.html",
                "template": "html!./index.html"
            })
        ],
        module: {
            loaders: [
            { test: /\.tsx?$/, loader: "ts-loader" },
            ]
        }
    }, 
    {
        output: {
            path: "./dist",
            filename: "bundle.js"
        },
        plugins: [
            new HtmlWebpackPlugin({
                "filename": "./index.html",
                "template": "html!./index.html"
            })
        ]    
    }
]

It seems to work fine, but the script bundle.js is not injected into the index.html as expected. The HtmlWebpackPlugin is supposed to do this. What am I doing wrong?

Upvotes: 11

Views: 15254

Answers (2)

biodiscus
biodiscus

Reputation: 880

The HTML Bundler plugin for Webpack can read template files in a source directory and save compiled HTML files with the same structure in the output directory.

For example, there are templates in the src/views/ source directory:

src/views/index.html
src/views/about/index.html
src/views/news/sport/index.html
src/views/news/sport/hockey/index.html
src/views/news/sport/football/index.html
...

We want to have the same folder structure in the dist/ directory:

dist/index.html
dist/about/index.html
dist/news/sport/index.html
dist/news/sport/hockey/index.html
dist/news/sport/football/index.html
...

Just install the html-bundler-webpack-plugin:

npm install html-bundler-webpack-plugin --save-dev

Add the plugin in the Webpack config:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlBundlerPlugin({
      entry: 'src/views/', // the template directory
    }),
  ],
};

All templates from the src/views/ directory will be compiled and saved in the dist/ directory with the same structure. All source script and style files referenced in HTML will be processed automatically.

Upvotes: 0

jantimon
jantimon

Reputation: 38142

This is similar to WebpackHtmlPlugin issue #234.

From https://github.com/webpack/docs/wiki/configuration#outputpublicpath

output.publicPath The publicPath specifies the public URL address of the output files when referenced in a browser.

What you can do is to add the 'app' folder name to the output filename:

module.exports = {
  output: {
    filename: "app/[name]-[hash].js",
    path: "dist",
    publicPath: ""
  },
  plugins: [
    new HtmlWebpackPlugin({
       "template": "html!./index.html"
    }),
  ],
}

Upvotes: 2

Related Questions