npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

generate-file-webpack-plugin

v1.0.1

Published

General purpose Webpack plugin for generating files.

Downloads

13,430

Readme

MIT license CI (master) dependencies dev-dependencies

generate-file-webpack-plugin

General purpose Webpack plugin for generating files.

Getting Started

Requirements

  • Webpack 4.x

    • Earlier version of Webpack probably won't work.
    • Latest version 5.x may work, but has not been tested.
  • Node.js 12.x

    • Earlier versions may also work, but have not been tested.
    • Later versions most probably also work, but have not been tested.
  • npm 6.x

    • Earlier versions may also work, but have not been tested.
    • Later versions most probably also work, but have not been tested.

Install

Using npm:

npm install generate-file-webpack-plugin --save-dev

Even if not been tested yet, installation using yarn should work without problems:

yarn add generate-file-webpack-plugin --dev

Usage

webpack.config.js

const generate = require('generate-file-webpack-plugin');

module.exports = {
    // ...
    plugins: [
       generate({
            file: 'output.txt',
            content: 'Hello World'
        })
    ]
};

Running webpack via your preferred method will generate a file named output.txt in your root output directory with the content Hello World.

Configuration

webpack.config.js

const generate = require('generate-file-webpack-plugin');

module.exports = {
    // ...
    plugins: [
       generate(options)
    ]
};

Thereby, options is the main configuration object for this plugin, supporting the following properties:

file

The file that is to be generated.

This may either be a relative or an absolute file path. In case it is a relative file path, it will be resolved relative to the output.path you specified in your webpack configuration.

  • type: string
  • required: true
  • since: 1.0.0

content

The content to be written into the specified file.

This property is designed to be quite flexible, in order to cover as much use cases as possible. In its simplest form it is just a string or a Buffer. But it may also be a Promise that will later resolve to either a string or a Buffer. Further, it may be a Function that either returns a string or a Buffer, or a Promise resolving to one of the aforementioned types.

debug

Flag, indicating if additional debug output should be logged.

  • type: boolean
  • required: false
  • default: false
  • since: 1.0.0

Examples

Copy File

Given, you have a file my-file.txt in your src directory. Then you can copy that file into webpack's default output directory like this:

const fs = require('fs');
const generate = require('generate-file-webpack-plugin');

module.exports = {
    // ...
    plugins: [
       generate({
            file: 'my-file.txt',
            content:  fs.readFileSync(path.resolve(__dirname, 'src/my-file.txt'))
        })
    ]
};

Note, that this plugin's intend is not to replace the well known copy webpack plugin. In case you just want to copy over some file into webpack's output directory, you'll probably be better suited to use the copy-webpack-plugin, since it may be easier to use for this case.

Nevertheless, this plugin got some features, that make it extremely useful in more complex scenarios as described in the following examples.

Generate Application Info

Say, you want to generate some metadata information for your app, that is to served by a web server and displayed in your application on demand, you can do it like this:

const fs = require('fs');
const path = require('path');
const generate = require('generate-file-webpack-plugin');

// Load package.json as object
const appPackage = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'package.json')).toString());

module.exports = {
    // ...
    plugins: [
        generate({
            file: 'app-info.js',
            content: `const appInfo = {
                name: "${appPackage.name}",
                version: "${appPackage.version}"
            }`
        })
    ]
};

This will generate a file app-info.js with the name and the version of the app, that can be served and included by your web application, using the following tag:

<script type="text/javascript" language="javascript" src="app-info.js"></script>

Note, that this approach of specifying the content of the generated file as a (template) string has several drawbacks:

  • The package.json object is created as a global variable.
  • The content will be resolved as soon as the webpack configuration is loaded, and not at the time the plugin is actually executed. This is OK in this case, but there may be situations where referenced information is not available at the time the webpack configuration is being loaded.

We can circumvent those issues by using a function as the content source for the generated file, like this:

const fs = require('fs');
const path = require('path');
const generate = require('generate-file-webpack-plugin');

module.exports = {
    // ...
    plugins: [
        generate({
            file: 'app-info.js',
            content: () => {
                const appPackage = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'package.json')).toString());
                return `const appInfo = {
                            name: "${appPackage.name}",
                            version: "${appPackage.version}"
                        }`
            }
        })
    ]
};

Note, that we used an anonymous arrow function in this case. We could have also used a "regular" anonymous function, or a named function declared in the webpack configuration.

We can further enhance this example by not only using information from the package.json, but also from a different information source. It would be useful to add an unique identifier (called hash in this case) for the source code from which the application has been build. We use the latest Git commit ID for that in this example. This can be done like this:

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const generate = require('generate-file-webpack-plugin');

module.exports = {
    // ...
    plugins: [
        generate({
            file: 'app-info.js',
            content: () => {
                const appPackage = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'package.json')).toString());
                const lastCommitId = execSync('git rev-parse HEAD', {timeout: 1000}).toString().trim();
                return `const appInfo = {
                            name: "${appPackage.name}",
                            version: "${appPackage.version}",
                            hash: "${lastCommitId}"
                        }`
            }
        })
    ]
};

Just for readability, we can extract parsing of the package.json file and the retrieval of the latest Git commit ID into named functions declared in the webpack configuration.

Note: Calling functions from within a content function is allowed.

module.exports = {
    // ...
    plugins: [
        generate({
            file: 'app-info.js',
            content: () => {
                const appPackage = parseAppPackage();
                const lastCommitId = getLastCommitId();
                return `const appInfo = {
                            name: "${appPackage.name}",
                            version: "${appPackage.version}",
                            hash: "${lastCommitId}"
                        }`
            }
        })
    ]
};

function parseAppPackage() {
    return JSON.parse(fs.readFileSync(path.resolve(__dirname, 'package.json')).toString());
}

function getLastCommitId() {
    return execSync('git rev-parse HEAD', {timeout: 1000}).toString().trim();
}

Using Handlebars Templates

Picking up the Generate Application Info example, we can also use the handlebars template engine for generating our app-info.js file (or any other file you like).

First, we have to install the handlebars npm package:

npm install handlebars --save-dev

Then, we have to create a handlebars template file, for generating our app-info.js file, for this example located in src/app-info.hbs:

const appInfo = {
    name: "{{appPackage.name}}",
    version: "{{appPackage.version}}",
    hash: "{{lastCommitId}}"
}

Finally, we add the following to our webpack configuration:

const handlebars = require('handlebars');
const generate = require('generate-file-webpack-plugin');

module.exports = {
    // ...
    plugins: [
        generate({
            file: 'app-info.js',
            content: () => {
                return template('src/app-info.hbs')({
                    appPackage: parseAppPackage(),
                    lastCommitId: getLastCommitId()
                });
            }
        })
    ]
};

function template(file) {
    return handlebars.compile(fs.readFileSync(path.resolve(__dirname, file)).toString());
}

Note, that for clarity we omitted the definition of the parseAppPackage() and getLastCommitId() functions. Have a look at the Generate Application Info example if you need to know how they are implemented.

Note, that we defined a (more or less) generic function template(file) for compiling our handlebars template file. We are not relying on the handlebars-loader webpack loader, because the webpack configuration setup for making this work would be too complex. Especially, we would have to defined an entry point for the loader, and still could not ensure that our plugin gets executed after the loader has done its work. In theory we could somehow make it work, but in reality this is just a configuration overkill that you should avoid.

Generate Multiple Files

In order to generate multiple files, you have to specify multiple invocations of this plugin in the webpack configuration, like this:

module.exports = {
    // ...
    plugins: [
        generate({
            file: 'file-1.txt',
            content: 'some content for file 1'
        }),
        generate({
            file: 'file-2.txt',
            content: 'some content for file 2'
        })
    ]
};

Of course you can use all of the features described in previous examples for specifying the content.

Known Problems

See bugs