How can I inject a build number with webpack?

后端 未结 7 960
野的像风
野的像风 2021-01-30 10:38

I\'d like to inject a build number and version information to my project as it\'s built with webpack. For example, so that my code can do something like:

var bui         


        
相关标签:
7条回答
  • 2021-01-30 10:48

    I would do more simpler, just use npm version patch (npm-version) (no plugin required)

    package.json (Example path version before building)

    {
      "version": "1.0.0",
      "scripts": {
        "build": "npm version patch && node build/build.js"
      }
    }
    

    So when you run npm run build this will patch the version (1.0.0 to 1.0.1 in your package.json)


    Bonus: You can also add this to your config (example config/prod.env.js)

    'use strict'
    const pkg = require('./package.json')
    module.exports = {
      NODE_ENV: '"production"',
      VERSION: pkg.version
    }
    

    Then you can use process.env.VERSION anywhere in your our JS

    Updated: Or just use process.env.npm_package_version without required to include package.json

    0 讨论(0)
  • 2021-01-30 10:52

    You can use the DefinePlugin that will make your build info available inlined with your code:

    Config

    new webpack.DefinePlugin({
       __VERSION__: JSON.stringify('12345')
    })
    

    App code

    console.log(__VERSION__);
    
    0 讨论(0)
  • 2021-01-30 10:53

    There is a plugin to auto inject version from package.json. It can inject it into HTML, CSS, JS as a comment, but also as a value by special tag webpack-auto-inject-version.

    How to:

    First of all, you have to add it to your project:

    npm i webpack-auto-inject-version
    

    Then you need to set up your webpack config:

    var WebpackAutoInject = require('webpack-auto-inject-version');
    
    module.exports = {
        plugins: [
            new WebpackAutoInject()
        ]
    }
    

    As you want to inject it into javascript, you should add a tag inside your javascript file ( which will be changed to version during the webpack compilation )

    var version = '[AIV]{version}[/AIV]';
    console.log(version);
    

    Auto increasing:

    You can set it up to auto increase the version directly from webpack by:

    webpack --other-webpack-settings --major
    
    webpack --other-webpack-settings -- minor
    
    webpack --other-webpack-settings --patch
    

    Where --other-webpack-settings is equal to your custom line args. Simplifying - you need to att --major, --minor or --patch whenever you want to auto increase a version.

    0 讨论(0)
  • 2021-01-30 10:56

    I have two files that I distribute that have the build number from the viewpoint of both git and npm (package.json). I'd still like to pull this into my index.template.html in a meta tag, but haven't figured that out yet (how can I make a DEFINE from file contents or a cmd output?).

    For git, I use webpack-shell-plugin to make a file with the git info:

    const WebpackVersionFilePlugin = require('webpack-version-file-plugin');
    plugins: [
    new WebpackShellPlugin({
          onBuildStart: [
            'git name-rev --name-only HEAD > dist/gitversion.txt',
            'git rev-list HEAD --count >> dist/gitversion.txt',
            'git rev-parse HEAD >> dist/gitversion.txt']
        }),
    

    For npm, I add the npm version command ("npm version patch/minor/major") to (1) ensure there is no outstanding uncommitted changes in git - it fails if there are any and (2) update the package.json version and check it into git.

      "scripts": {
        "build": "npm run lint && npm run init && npm version patch && webpack --config webpack.config.js",
    

    I then distribute that using poorly documented, probably buggy, WebpackVersionFilePlugin.

    const WebpackVersionFilePlugin = require('webpack-version-file-plugin');
    new WebpackVersionFilePlugin({
          packageFile:path.join(__dirname, 'package.json'),
          outputFile: path.join('./dist/', 'version.json')
        }),
    

    Using this template in the top directory:

    {
      "version" : {
        "name":      "<% package.name %>",
        "buildDate": "<%= currentTime %>",
        "version":   "<%= package.version %>"
      }
    }
    

    Neither "package.name" nor "name" work.

    The result is two files in my ./dist/directory. gitversion.txt (branch, commit, count from head):

    fmwk/feathers
    9cfe791a09d3d748e8120e0628
    51
    

    and version.json:

    {
      "version" : {
        "name":      "",
        "buildDate": "Fri Oct 21 2016 11:10:12 GMT+0800 (PHT)",
        "version":   "0.6.2"
      }
    }
    
    0 讨论(0)
  • 2021-01-30 10:59

    I couldn't get this to work with TypeScript, so I helped myself by creating a file upon every compilation.

    webpack.config.js

    const fs = require('fs'); 
    const path = require('path'); 
    fs.writeFileSync(path.resolve(path.join(__dirname, 'src/version.ts')), 
    `// This file is auto-generated by the build system. 
    const BundleVersion = "${ new Date().toISOString().substr(0, 10) }"; 
    export default BundleVersion; 
    `); 
    

    Then I just import BundleVersion from './version'; and make sure it actually gets used somewhere (console.log or exposing it somewhere), so it is not being tree-shaken out, and that's it, timestamp (or version) in the bundle, created at compilation time (straight forward from here to read the package.json and use the package version if needed).

    0 讨论(0)
  • 2021-01-30 11:12

    Here is my recipe, derived from the other answers to this question. This makes use of the WebpackVersionFilePlugin and execa, and works great for me right now.

    Install the plugins via npm:

    npm install webpack-version-file-plugin --save-dev
    npm install execa --save-dev
    

    webpack.config.js:

    const WebpackVersionFilePlugin = require('webpack-version-file-plugin');
    const execa = require('execa');
    
    const gitHash = execa.sync('git', ['rev-parse', '--short', 'HEAD']).stdout;
    const gitNumCommits = Number(execa.sync('git', ['rev-list', 'HEAD', '--count']).stdout);
    const gitDirty = execa.sync('git', ['status', '-s', '-uall']).stdout.length > 0;
    
    module.exports = {
    // ... snip ...
    plugins: [
        new WebpackVersionFilePlugin({
            packageFile: path.join(__dirname, 'package.json'),
            template: path.join(__dirname, 'version.ejs'),
            outputFile: path.join('build/ts/', 'version.json'),
            extras: {
                'githash': gitHash,
                'gitNumCommits': gitNumCommits,
                'timestamp': Date.now(),
                'dirty': gitDirty
            }
        }),
    // ... snip ...
    

    version.ejs (in project root):

    {
        "name":       "<%= package.name %>",
        "buildDate":  <%= extras.timestamp %>,
        "version":    "<%= package.version %>",
        "numCommits": <%= extras.gitNumCommits %>,
        "hash":       "<%= extras.githash %>",
        "dirty":      <%= extras.dirty %>
    }
    

    So far, running this gets us a version.json file in build/ts with this content:

    {
        "name":       "app name from package.json",
        "buildDate":  1518774257225,
        "version":    "2.0.1",
        "numCommits": 148,
        "hash":       "5a74b7a",
        "dirty":      false
    }
    

    The dirty flag indicates if the build included uncommitted or untracked changes.

    I use TypeScript, so the following describes how to get the JSON file into my TypeScript code. If you don't have TypeScript, we have still reduced the problem to reading a JSON file. :-)

    app.ts:

    import * as appVersionJson from './version.json';
    
    export const appVersion: AppVersion = <any>appVersionJson;
    
    export interface AppVersion {
        /** application name as specified in package.json */
        readonly name: string;
    
        /** build timestamp in milliseconds since the epoch */
        readonly buildDate: number;
    
        /** application version as specified in package.json */
        readonly version: string;
    
        /** number of commits in the Git repo */
        readonly numCommits: number;
    
        /** latest Git commit hash */
        readonly hash: string;
    
        /** flag is set when uncommitted or untracked changes are present in the workspace */
        readonly dirty: boolean;
    }
    
    // ...snip...
    // now just use it in methods, for example:
    appVersion.version + '.' + appVersion.numCommits + ' (' + appVersion.hash + ')'
    

    Alright - hope this provides some more clues on how to have good build number information available in the code. Btw, npm version is a good way to bump the version numbers, when working like this.

    0 讨论(0)
提交回复
热议问题