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

Standalone chartjs build (don't include moment.js) #124

Closed
CalebKester opened this issue Jun 20, 2017 · 16 comments
Closed

Standalone chartjs build (don't include moment.js) #124

CalebKester opened this issue Jun 20, 2017 · 16 comments

Comments

@CalebKester
Copy link

Expected Behavior

Moment.js shouldn't be included

Actual Behavior

Moment.js appears on my package.lock file and gets bundled in my build

Environment

  • vue.js version: 2.3.3
  • vue-chart.js version: 2.6.0
  • npm version: 5.0.3
  • webpack: 2.5.1

Can you help me figure out how I configure this correctly so that I only get the standalone chart.js build: https://github.com/chartjs/Chart.js/blob/3e94b9431a5b3d6e4bfbfd6a2339a350999b3292/docs/getting-started/installation.md . Moment.js is a very heavy package and if I can avoid including it in my site I'll gladly do that. The documentation makes it sound like treeshaking can do this but I'm just using the vue webpack cli and it's still coming through.

Thanks

@apertureless
Copy link
Owner

Hey @CalebKester

to be honest, I am not completely sure 🤔 if this is possible.

I don't think that treeshaking will work. Because it only works on es modules. And neither Chart.js nor moment.js are available as es modules. AFAIK.

Thats a reason, why I have extra es modules output in vue-chartjs . https://github.com/apertureless/vue-chartjs/blob/develop/package.json#L39-L42

The problem is, that I am simply importing chart.js over import Chart from 'chart.js' and I guess it will grab the version with moment.js included. However I am not completely sure, because the pasckage.json of Chart.js seems weird, as the index is set to the src/Chart.js and not to the bundled dist files.

So I guess, if you're using import you can't grab the standalone one. However I will check the docs of Chart.js

@throrin19
Copy link

I Have the same problem Here.

I load chartJs like that :

import { Bar } from 'vue-chartjs';

But, in compilation, I have momentJS in the bundle :/

@apertureless
Copy link
Owner

apertureless commented Feb 5, 2018

That is because if you import Chart from 'chart.js' you will get the bundled one (with moment.js).
There are some issues at chart.js to kill moment.js and replace it with date-fns. However I don't know if it will happend.

I would love to change that, however it would be confusing to break with the standard behaviour of the chart.js npm package. So the solution needs to be on user side right now.

💍 Solution

You need to add an alias to your webpack config, so it will grab the standalone version

webpack.config.js

resolve: {
    alias: {
      'chart.js': 'chart.js/dist/Chart.js'
    }
}

This way it will grab the standalone version.

xj3Ie4rLNuLSM

@throrin19
Copy link

Thanks. It works

@himynameisubik
Copy link

himynameisubik commented Apr 6, 2019

Sorry, I might be doing something wrong but I can't get this to work:
vue.config.js

configureWebpack: {
      resolve: {
          alias: {
              'chart.js': 'chart.js/dist/Chart.js'
          }
      }
}

With that moment.js still ends up in my chunk-files. Any idea?

I'm importing the line chart like this:

import { Line } from 'vue-chartjs'
  • Also using Vue-cli 3

@apertureless
Copy link
Owner

I think this is not possible anymore.
Because it was kind of a bug of chart.js that they did not include momentjs in the chart.js/dist/Chart.js build.

Not as far as I understand it is bundled in both version.

@himynameisubik
Copy link

himynameisubik commented Apr 6, 2019

Oh damn, really? So I'm stuck with having moment.js in my project even though I never use it. It's literally the largest chunk in my whole project. Thanks for your answer though!

Update:
I was able to exclude it by using

vue.config.js

configureWebpack: {
    externals: {
        moment: 'moment'
    }
}

I don't know if it has any other impacts besides moment.js is gone and my full project shrunk by about 250kb.

@himynameisubik
Copy link

Seems it works fine. No issues for now.

@apertureless
Copy link
Owner

I think it will work as long as you do not use any chart.js features that rely on momentjs.

@himynameisubik
Copy link

Yes of course. But that would‘ve been the same with only using the standalone in earlier version, no?

@J3m5
Copy link

J3m5 commented Apr 7, 2019

Hi!

First of all, I would like to thank you for vue-charts, it's really great!

The standalone build does not include moment (except if you use webpack) as mentioned here since 2.8.0, it was implemented in the PR chartjs/Chart.js#5978 .

This is also to allow us to choose an other date library, now there is adapters, as implemented in chartjs/Chart.js#5960 . There are two adapters at this time, one for luxon and another for date-nfs.

It would be really nice to add a way to select the build we want and use the adapters we'd like.

I'm planning to switch to date-fns as soon as I can to reduce the size of my builds by using Date-nfs because it can benefits from treeshaking and is lighter than moment.

@himynameisubik
Copy link

Strange, building my project with the standalone (general npm package) adds moment to it. Maybe I need to change my chartjs npm installation.

@J3m5
Copy link

J3m5 commented Apr 7, 2019

In fact, it is included by default if you use webpack so you are right, you need to manually remove it as stated here.

@himynameisubik
Copy link

Yes exactly, that‘s what I did and commented here: #124 (comment)

@SergeiMinaev
Copy link

I use rollup. After excluding moment.js with external: ['moment'] I got this error:

SyntaxError: import declarations may only appear at top level of a module

because there was import { moment } from 'moment'; at top of my bundle.js:

This plugin helped me: https://github.com/proteriax/rollup-plugin-ignore
Notice: 'ignore' plugin should be placed before others. Also, there is no need to use external: ['moment'] if you use rollup-plugin-ignore.

My rollup.config.js:

...
import ignore from "rollup-plugin-ignore";
...
plugins: [
  ignore(['moment']),
  ...
]

@souljorje
Copy link

@SergeiMinaev thanks, it helped me with some additions! Why should it be placed before others? really wasn't working until I placed it on the top.

I'm using vite. When I tried to exclude moment.js with external: ['moment'], I faced this error: Uncaught TypeError: Failed to resolve module specifier "moment". Relative references must start with either "/", "./", or "../".

"chart.js": "^2.9.3",
"rollup-plugin-ignore": "^1.0.9",
"vite": "^2.5.0",

This worked:

import ignore from 'rollup-plugin-ignore';

export default () => defineConfig({
  plugins: [
    ignore(['moment', 'moment?commonjs-require']), // need to add also moment?commonjs-require, otherwise doesn't work, couldn't find out why 🤷‍♂️
  ],
});

I submitted PR alex-kinokon/rollup-plugin-ignore#5 to rollup-plugin-ignore, check it's status, maybe it won't be needed to add ?commonjs-require anymore.

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

7 participants