Rikard
Rikard

Reputation: 7805

webpack import only variable value

I'm compiling code that needs the version value from package.json:

import {version} from '../package.json';
export default {version};

and when I look at the .js file that webpack outputs I see the whole package.json there!

How can I avoid this?

My setup is:

plugins: [
    new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"production"'
    }),
    new webpack.optimize.UglifyJsPlugin({
        compress: {
            warnings: false
        }
    }),
    new CompressionPlugin({
        asset: '[path].gz[query]',
        algorithm: 'gzip',
        test: /\.(js|css)$/,
        threshold: 10240,
        minRatio: 0.8
    }),
]

My webpack version is 3.8.1

Upvotes: 5

Views: 1025

Answers (2)

João Cunha
João Cunha

Reputation: 10307

What I usually do is take advantage of the DefinePlugin

// webpack.config.js
// getting the version
const package = require("./package.json");
const version = package.version;

plugins: [
    new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"production"',
        'process.env.VERSION': version,
    }),
    new webpack.optimize.UglifyJsPlugin({
        compress: {
            warnings: false
        }
    }),
    new CompressionPlugin({
        asset: '[path].gz[query]',
        algorithm: 'gzip',
        test: /\.(js|css)$/,
        threshold: 10240,
        minRatio: 0.8
    }),
]

Now in your code all you gotta do is use process.env.VERSION and you it will output your packages version.

Hope it helped

Upvotes: 7

Vladislav Ihost
Vladislav Ihost

Reputation: 2187

Modern webpack versions support Tree shaking (https://webpack.js.org/guides/tree-shaking/ ), but it works only if export directives are configured by special scheme, includes independent named import for each entity. In that case webpack can perform analyze dependencies graph and include only required entities. Also, import directive does not support destructing - it's only syntax for named import, so large JS object will be always imported in monolithic style.

Import as value is unavailable by definition, because webpack performs only bundling for set of files with source code and maybe custom resources dependencies. Real imports in ES6 modules, which today are already supported on most platforms, also do not provide values imports - instead it's binding. https://ponyfoo.com/articles/es6-modules-in-depth#bindings-not-values.

Of course, original problem can be solved by webpack replace or alias plugins. Just store version in some independent file or string constant and substitute it due bundling. Most straightforward solution is

import version from 'PACKAGE_VERSION'

and then configure external with callback https://webpack.js.org/configuration/externals/ like that

externals: [
  function(context, request, callback) {
    if (request === 'PACKAGE_VERSION'){
      return callback(null, 'exports.default = ' + JSON.stringify(JSON.parse(fs.readFileSync('package.json')).version));
    }
    callback();
  }
],

Upvotes: 2

Related Questions