Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce build size #32

Closed
ankurk91 opened this issue Sep 23, 2017 · 2 comments
Closed

Reduce build size #32

ankurk91 opened this issue Sep 23, 2017 · 2 comments

Comments

@ankurk91
Copy link

ankurk91 commented Sep 23, 2017

Hi,
I was trying to reduce my webpack bundle size.
I found that you are also packing accounting-js in your "dist".
You can exclude this be tweaking your webpack config.

  entry: './src/index.js',
  externals: [
    'vue',
    'accounting-js',
  ],

Don't worry; your dist file will still has a reference to accounting-js and will be included by developer webpack.

Benefits

  • This will reduce this package size to ~ 4kb
  • Better debugging because dist does not include any 3rd party code
  • Take advantage of webpack tree shaking
  • Prevent duplicate bundling when a developer has also installed accounting-js as dependency in his project

Cons

  • When using this package without webpack (directly in browser); end user need to include accounting-js just before this script.

Findings

Thanks.

@ankurk91
Copy link
Author

ankurk91 commented Sep 23, 2017

Here is the optimized dist - (4kb when minified)

!function (e, t) {
  "object" == typeof exports && "object" == typeof module ? module.exports = t(require("accounting-js")) : "function" == typeof define && define.amd ? define("VueNumeric", ["accounting-js"], t) : "object" == typeof exports ? exports.VueNumeric = t(require("accounting-js")) : e.VueNumeric = t(e["accounting-js"])
}(this, function (e) {
  return function (e) {
    function t(r) {
      if (n[r]) return n[r].exports;
      var u = n[r] = {i: r, l: !1, exports: {}};
      return e[r].call(u.exports, u, u.exports, t), u.l = !0, u.exports
    }

    var n = {};
    return t.m = e, t.c = n, t.d = function (e, n, r) {
      t.o(e, n) || Object.defineProperty(e, n, {configurable: !1, enumerable: !0, get: r})
    }, t.n = function (e) {
      var n = e && e.__esModule ? function () {
        return e.default
      } : function () {
        return e
      };
      return t.d(n, "a", n), n
    }, t.o = function (e, t) {
      return Object.prototype.hasOwnProperty.call(e, t)
    }, t.p = "", t(t.s = 0)
  }([function (e, t, n) {
    "use strict";
    Object.defineProperty(t, "__esModule", {value: !0});
    var r = n(1), u = {
      install: function (e) {
        e.component(r.name, r)
      }
    };
    r.install = u.install, t.default = r
  }, function (e, t, n) {
    "use strict";
    Object.defineProperty(t, "__esModule", {value: !0});
    var r = n(3), u = n(5), i = n(2), o = i(r.a, u.a, null, null, null);
    t.default = o.exports
  }, function (e, t) {
    e.exports = function (e, t, n, r, u) {
      var i, o = e = e || {}, a = typeof e.default;
      "object" !== a && "function" !== a || (i = e, o = e.default);
      var s = "function" == typeof o ? o.options : o;
      t && (s.render = t.render, s.staticRenderFns = t.staticRenderFns), r && (s._scopeId = r);
      var c;
      if (u ? (c = function (e) {
          e = e || this.$vnode && this.$vnode.ssrContext || this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext, e || "undefined" == typeof __VUE_SSR_CONTEXT__ || (e = __VUE_SSR_CONTEXT__), n && n.call(this, e), e && e._registeredComponents && e._registeredComponents.add(u)
        }, s._ssrRegister = c) : n && (c = n), c) {
        var l = s.functional, d = l ? s.render : s.beforeCreate;
        l ? s.render = function (e, t) {
          return c.call(t), d(e, t)
        } : s.beforeCreate = d ? [].concat(d, c) : [c]
      }
      return {esModule: i, exports: o, options: s}
    }
  }, function (e, t, n) {
    "use strict";
    var r = n(4), u = n.n(r);
    t.a = {
      name: "vue-numeric",
      props: {
        currency: {default: "", required: !1, type: String},
        max: {default: Number.MAX_SAFE_INTEGER, required: !1, type: Number},
        min: {default: Number.MIN_SAFE_INTEGER, required: !1, type: Number},
        minus: {default: !1, required: !1, type: Boolean},
        placeholder: {required: !1, type: String},
        precision: {required: !1, type: Number},
        separator: {default: ",", required: !1, type: String},
        value: {default: 0, required: !0, type: [Number, String]},
        readOnly: {default: !1, required: !1, type: Boolean},
        readOnlyClass: {default: "", required: !1, type: String},
        currencySymbolPosition: {default: "prefix", required: !1, type: String}
      },
      data: function () {
        return {amount: ""}
      },
      computed: {
        amountNumber: function () {
          return this.unformat(this.amount)
        }, valueNumber: function () {
          return this.unformat(this.value)
        }, decimalSeparator: function () {
          return "." === this.separator ? "," : "."
        }, thousandSeparator: function () {
          return "." === this.separator ? "." : ","
        }, symbolPosition: function () {
          return this.currency ? "suffix" === this.currencySymbolPosition ? "%v %s" : "%s %v" : "%v"
        }
      },
      methods: {
        onBlurHandler: function () {
          this.amount = this.format(this.valueNumber)
        }, onFocusHandler: function () {
          this.amount = this.valueNumber
        }, onInputHandler: function () {
          this.process(this.amountNumber)
        }, process: function (e) {
          e >= this.max && this.update(this.max), e <= this.min && this.update(this.min), e > this.min && e < this.max && this.update(e), !this.minus && e < 0 && (this.min >= 0 ? this.update(this.min) : this.update(0))
        }, update: function (e) {
          this.$emit("input", Number(u.a.toFixed(e, this.precision)))
        }, format: function (e) {
          return u.a.formatMoney(e, {
            symbol: this.currency,
            format: this.symbolPosition,
            precision: Number(this.precision),
            decimal: this.decimalSeparator,
            thousand: this.thousandSeparator
          })
        }, unformat: function (e) {
          return u.a.unformat(e, this.decimalSeparator)
        }
      },
      watch: {
        valueNumber: function (e, t) {
          this.amountNumber !== e && this.amountNumber === t && (this.amount = e, this.$refs.numeric !== document.activeElement && (this.amount = this.format(e)))
        }, readOnly: function (e, t) {
          var n = this;
          !1 === t && !0 === e && this.$nextTick(function () {
            n.$refs.readOnly.className = n.readOnlyClass
          })
        }
      },
      mounted: function () {
        var e = this;
        this.placeholder || (this.process(this.valueNumber), this.amount = this.format(this.valueNumber), setTimeout(function () {
          e.process(e.valueNumber), e.amount = e.format(e.valueNumber)
        }, 500)), this.readOnly && (this.$refs.readOnly.className = this.readOnlyClass)
      }
    }
  }, function (t, n) {
    t.exports = e
  }, function (e, t, n) {
    "use strict";
    var r = function () {
      var e = this, t = e.$createElement, n = e._self._c || t;
      return e.readOnly ? n("span", {ref: "readOnly"}, [e._v(e._s(e.amount))]) : n("input", {
        directives: [{
          name: "model",
          rawName: "v-model",
          value: e.amount,
          expression: "amount"
        }],
        ref: "numeric",
        attrs: {placeholder: e.placeholder, type: "tel"},
        domProps: {value: e.value, value: e.amount},
        on: {
          blur: e.onBlurHandler, input: [function (t) {
            t.target.composing || (e.amount = t.target.value)
          }, e.onInputHandler], focus: e.onFocusHandler
        }
      })
    }, u = [], i = {render: r, staticRenderFns: u};
    t.a = i
  }])
});

package.json

"devDependencies": {
    "babel-core": "^6.25.0",
    "babel-loader": "^7.1.0",
    "babel-preset-env": "^1.6.0",
    "clean-webpack-plugin": "^0.1.16",
    "css-loader": "^0.28.4",
    "file-loader": "^0.11.1",
    "html-webpack-plugin": "^2.30.1",
    "style-loader": "^0.18.1",
    "vue": "^2.4.2",
    "vue-loader": "^13.0.4",
    "vue-template-compiler": "^2.4.2",
    "webpack": "^3.5.3",
    "webpack-dev-server": "^2.7.1"
  },
  "peerDependencies": {
    "vue": "^2.0.0"
  },

webpack.config.js

'use strict';

const webpack = require('webpack');
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  context: __dirname,
  resolve: {
    modules: [
      path.resolve(__dirname, 'src'),
      'node_modules'
    ],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['.js', '.jsx', '.json', '.vue']
  },
  entry: './src/index.js',
  // Don't include theme into library build
  externals: [
    'vue',
    'accounting-js',
  ],
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: "vue-numeric.min.js",
    library: 'VueNumeric',
    libraryTarget: 'umd',
    umdNamedDefine: true,
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: path.resolve(__dirname, 'node_modules'),
      },
    ]
  },
  plugins: [
    new CleanWebpackPlugin(['./dist']),
  ],
  devtool: false,
  performance: {
    hints: false,
  }
};

.babelrc

{
  "presets": [
    [
      "env",
      {
        "modules": false,
        "targets": {
          "browsers": [
            "> 2%"
          ],
          "uglify": true
        }
      }
    ]
  ]
}

@ankurk91 ankurk91 changed the title Don't pack accounting-js in build Reduce build size Sep 23, 2017
@kevinongko
Copy link
Owner

Thanks, didn't know the istanbul plugin can cause bigger build size, fixed in 2.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants