Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRefactors circular dependencies #2389
Conversation
amenadiel
force-pushed the
HuasoFoundries:refactor_circular_deps
branch
2 times, most recently
from
1d26672
to
ad63924
Jun 11, 2018
amenadiel
force-pushed the
HuasoFoundries:refactor_circular_deps
branch
from
8e9cf64
to
0b7bf8d
Jun 11, 2018
This comment has been minimized.
This comment has been minimized.
codecov-io
commented
Jun 11, 2018
•
Codecov Report
@@ Coverage Diff @@
## master #2389 +/- ##
==========================================
+ Coverage 77.23% 78.05% +0.81%
==========================================
Files 51 52 +1
Lines 4138 4137 -1
==========================================
+ Hits 3196 3229 +33
+ Misses 942 908 -34
Continue to review full report at Codecov.
|
amenadiel
reviewed
Jun 11, 2018
@@ -31,7 +68,7 @@ export var isEmpty = function (o) { | |||
return typeof o === 'undefined' || o === null || (isString(o) && o.length === 0) || (typeof o === 'object' && Object.keys(o).length === 0); | |||
}; | |||
export var notEmpty = function (o) { | |||
return !c3_chart_internal_fn.isEmpty(o); | |||
return !c3.chart.internal.fn.isEmpty(o); |
This comment has been minimized.
This comment has been minimized.
amenadiel
Jun 11, 2018
Author
Contributor
You already have c3.chart.internal.fn
defined in this module, so you don't need to import it's alias from ./core
amenadiel
reviewed
Jun 11, 2018
@@ -13,7 +50,7 @@ export var isString = function (o) { | |||
return typeof o === 'string'; | |||
}; | |||
export var isUndefined = function (v) { | |||
return typeof v === 'undefined'; | |||
return typeof v === 'undefined'; |
This comment has been minimized.
This comment has been minimized.
amenadiel
reviewed
Jun 11, 2018
@@ -1,6 +1,5 @@ | |||
import CLASS from './class'; | |||
import { Component } from './core'; | |||
import { isValue, isFunction, isString, isEmpty } from './util'; | |||
import {isValue, isFunction, isString, isEmpty, Component } from './util'; |
This comment has been minimized.
This comment has been minimized.
amenadiel
Jun 11, 2018
Author
Contributor
Component is exported by ./util
so you don't need to import it from ./core
anymore
amenadiel
reviewed
Jun 11, 2018
@@ -9,7 +9,7 @@ | |||
"docs": "bundle exec middleman", | |||
"build": "npm run build:js && npm run build:css", | |||
"build:js": "npm run build:js:rollup && npm run build:js:uglify", | |||
"build:js:rollup": "rollup -c > c3.js", | |||
"build:js:rollup": "rollup -c", |
This comment has been minimized.
This comment has been minimized.
amenadiel
Jun 11, 2018
Author
Contributor
target output of rollup is configured on rollup.config.js
so you don't need to pipe STDOUT to a file explicitly
amenadiel
reviewed
Jun 11, 2018
banner: `/* @license C3.js v${pkg.version} | (c) C3 Team and other contributors | http://c3js.org/ */` | ||
banner: `/* @license C3.js v${pkg.version} | (c) C3 Team and other contributors | http://c3js.org/ */`, | ||
globals:{ | ||
d3:'d3' |
This comment has been minimized.
This comment has been minimized.
amenadiel
Jun 11, 2018
Author
Contributor
This will list d3
as a dependency in the top of the UMD build, instead of requiring d3
from ChartInternal
This comment has been minimized.
This comment has been minimized.
amenadiel
Jun 22, 2018
Author
Contributor
this one does no longer apply. D3 is required from inside ChartInternal as always
This comment has been minimized.
This comment has been minimized.
Thanks for the contribution! I agree with most changes. But I'd like to keep the timing of requiring d3 unchanged. Some users seem loading c3 and d3 in parallel, and this change breaks that situation. (We did the same change before and that caused the problem. See #2060 ) So I'd prefer keep it requiring inside ChartInternal constructor. Other part seems good to me |
This comment has been minimized.
This comment has been minimized.
I see. So the edge case scenario would be if someone loaded both d3 and c3 using But in that case, if you had no control over which script loaded first, you wouldn't either know when C3 has finished loading, and therefore you couldn't instance a new chart, unless you rely on setting a timeout. I don't know... keeping a require among ES6 modules seems suboptimal. I can rollback that specific part for this PR to be merged, anyway |
This comment has been minimized.
This comment has been minimized.
You are right. I guess probably they instanciate the chart after
I would appreciate if you rollback that part |
amenadiel
added some commits
Jun 22, 2018
kt3k
approved these changes
Jun 22, 2018
LGTM! Thanks for updating! Thanks for test additions as well! |
This comment has been minimized.
This comment has been minimized.
Okay, I restored the way $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined; However, regarding the inclusion of I was working in a branch that bundled c3 along d3. If you just import d3, the weight of the unminified build was roughly 900 kb. (which is the sum of the unminified builds of c3 and d3, give or take). BUT, if you only import the D3 components you really use: export var d3 = {
arc,
area,
brushSelection: brushSelection,
brushX: brushX,
brushY: brushY,
csv: csv,
curveBasis,
curveBasisClosed,
curveBasisOpen,
curveBundle,
curveCardinal,
curveCardinalClosed,
curveCardinalOpen,
curveLinear,
curveLinearClosed,
curveMonotoneX,
curveStep,
curveStepAfter,
curveStepBefore,
customEvent: customEvent,
drag: drag,
easeLinear: easeLinear,
extent: extent,
get event () { return event; },
get format () { return format; },
get formatPrefix () { return formatPrefix; },
get timeFormat () { return timeFormat; },
get timeParse () { return timeParse; },
get utcFormat () { return utcFormat; },
get utcParse () { return utcParse; },
interpolate: interpolate,
json: json,
line,
max: max,
merge: merge,
min: min,
mouse: mouse,
pie,
rgb: rgb,
scaleLinear: scaleLinear,
scaleTime: scaleTime,
schemeCategory10: schemeCategory10,
select: select,
selectAll: selectAll,
selection: selection,
selector: selector,
selectorAll: selectorAll,
set: set,
timeSecond: timeSecond,
transition: transition,
tsv: tsv,
zoom: zoom,
zoomIdentity: zoomIdentity,
}; The bundle size is ~ 650 kb, so you shave off 250kb from d3. It TL/DR Optional builds that bundle d3, using only required d3 imports. Can be built along regular
You can see those changes at HuasoFoundries@0f3e4d0 |
This comment has been minimized.
This comment has been minimized.
Hmm..smaller bundle looks interesting. It's good for lower bandwidth environment and possibly some users might be interested using it... Anyway we take this refactoring first. Thanks for the contributions! |
amenadiel commentedJun 11, 2018
•
edited
Curently, building with rollup using
npm run build:js
shows two warnings in the outputI've refactored the code in the following way:
src/util.js
contains the rootc3
object, as well as modulesChart
andComponent
so it doesn't need to import fromsrc/core
src/chart.js
imports everything it needs from./class
and./util
so it doesn't import from./core
thus removing the circular dependencysrc/core.js
imports alsoc3
,Chart
andComponent
fromsrc/util.js
src/chart-internal.js
which in turn importsd3
. Every other module doesn't used3
directly so this is the only component that should accessd3
.d3
is accessed, since using it asisn't the proper way to deal with external modules in the ES6 approach. Instead, it should be imported and listed in
rollup.config.js
as global/externalrollup.config.js
I added thefile
property to the output object, because it is the reccomended way to point to the generated file, so you can just callrollup -c
instead of doingrollup -c > c3.js
(this approach also allows to output to different files, such as an UMD build along an ES6 build, if you ever wanted to do so). Besides, this results in a friendlier build output avoiding to have the whole source code piped to STDOUT. Thepackage.json
has been modified accordingly.PD
The resulting UMD module (not included in the commit as per the PR directives) will either use global d3 or require it as:
Which accomplishes the same purpose of the old approach
This also allows an explicit AMD dependency using
define
instead ofrequire
, although requirejs and SystemJS should support using CommonJS requires as rell.