I am writing library and i have exports like this:
export function a(){ ... }
And using these functions as graphs.a()
After i added
import * as d3 from 'd3'
if i use library with
<script src="graphs.js"></script>
all is ok and module have functions, but when i use in node.js
import * as graphs from './graphs.js'
global.graphs = graphs
module 'graphs' contains no functions
Module {__esModule: true, Symbol(Symbol.toStringTag): "Module"}
Symbol(Symbol.toStringTag): "Module"
__esModule: true
__proto__: Object
Module using <script>
Module {__esModule: true, Symbol(Symbol.toStringTag): "Module"}
address_graph: (...)
address_sankey: (...)
query: (...)
Symbol(Symbol.toStringTag): "Module"
__esModule: true
get address_graph: ƒ ()
get address_sankey: ƒ ()
get query: ƒ ()
__proto__: Object
The import syntax only works if you're using a module bundler like Webpack or Rollup, or if you are using <script type="module">. What is your build system like?
If you could share an example repository that reproduces the behavior, it would help folks be able to debug.
Typically with Webpack, the build injects a <script> tag automatically into the HTML that points to the built bundle, so you should not need to include the <script> tag yourself. If you do, it might introduce conflicts or not work correctly.
If you want to import the library in Node, it needs to be built to a CommonJS module (that should be an output option of Webpack).
Related
I am using Laravel with Vue.js and Webpack / Laravel Mix.
I have Single File Components which should make use of Mixins.
The folder structure looks like this:
/app.js
/vue-components/Component.vue
/mixins/api/common.js
common.js defines a mixin like so:
export default {
// all content goes here
}
And when I import it from app.js and console.log it, it shows the data:
import industries from "./mixins/api/common";
console.log(industries); // this shows the content
Vue.component(
'some-component',
require("./vue-components/Component.vue")
);
Within Component.vue I use mixins: [ industries ], and that gives me the following error:
Component.vue?bb93:73 Uncaught ReferenceError: industries is not defined
Question 1:
Is it not possible to declare mixins globally and reference them from within a component?
To solve the issue I tried importing the mixin directly within the component instead of the global app.js file.
But import industries from "./mixins/api/common"; within Component.vue throws the following error while trying to compile with npm run:
This relative module was not found:
* ./mixins/api/common in ./node_modules/babel-loader/lib?{"cacheDirectory":true,"presets":[["env",{"modules":false,"targets":{"browsers":["> 2%"],"uglify":true}}]],"plugins":["transform-object-rest-spread",["transform-runtime",{"polyfill":false,"helpers":false}],"babel-plugin-syntax-dynamic-import","webpack-async-module-name"],"env":{"development":{"compact":false}}}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/assets/js/vue-components/Component.vue
Question 2:
If I have to import the mixin from within the Single File Components, what should the path look like?
As in Vue Document, You can declare mixin globally
//- build your mixin
const mixin = {
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
}
Vue.mixin(mixin)
new Vue({
myOption: 'hello!'
})
// "hello!"
You can also import mixin to use for each component.
In above your Component.vue, import path is not correct.
You should do import industries from "../mixins/api/common"
In my webpack config:
resolve: {
alias: {
'three': path.resolve('node_modules', 'three/build/three.js'),
'OrbitControls': path.resolve('node_modules', 'three/examples/js/controls/OrbitControls.js'),
'OBJLoader': path.resolve('node_modules', 'three/examples/js/loaders/OBJLoader.js')
}
In my module:
import * as THREE from 'three' // if I do import THREE from 'three' it fails with three being undefined
import OrbitControls from 'OrbitControls'
import OBJLoader from 'OBJLoader'
If I use import * THREE from 'three' all is well and I can get THREE to be defined and complete the cube tutorial without hassle. If I change to import * as THREE from 'three' three.js is loaded - so that's not the problem?
How do I get the OrbitControls and the OBJLoader to load? When I try to get them to load, I get Uncaught ReferenceError: THREE is not defined(…) within OrbitControls.js: THREE.OrbitControls = function ( object, domElement ) { THREE is undefined.
So there's a problem with the packaging of the modules? I installed this from https://www.npmjs.com/package/three
So what gives? Is it a problem how Three.js is packaged on npm or is it a misconfiguration in my webpack.config? Is there a way to tell webpack "let's package the root three.js file, and then package the OrbitControls.js file"?
I needed to install the three-orbit-controls and the three-obj-loader via npm.
Then in my module, it was simply requiring them:
var OBJLoader = require('three-obj-loader')(THREE)
var OrbitControls = require('three-orbit-controls')(THREE)
All set!
I am writing a test for a React component that uses react-router. I am using Mocha with Chai and Chai-jQuery.
My tests work fine, until I import a component from react-router into a component (e.g. Link). At this point, I get the following error:
ReferenceError: navigator is not defined
at Object.supportsHistory (/Users/nico/google-drive/code/agathos/client/node_modules/history/lib/DOMUtils.js:61:12)
I used to get a similar error with react-bootstrap until I updated to react-bootstrap v0.29.3. I have the most recent version of react-router v2.4.0 (and history v2.1.1). But the problem persists.
The only solution I have found is to change node_modules/history/lib/DOMUtils: navigator into window.navigator. This is a hack though, and not a good solution.
I think the problem is with react-router, but I don't have a solution.
Just in case, here is my test-helper.js.
import jquery from 'jquery';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import jsdom from 'jsdom';
import chai, { expect } from 'chai';
import chaiJquery from 'chai-jquery';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducers from './reducers';
// set up a testing environment to run like a browser in the command line
// create a fake browser and html doc
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = global.document.defaultView;
// prevent jquery defaulting to the dom by giving it access to the global.window
const $ = jquery(window);
// build renderComponent function that should render a React class
function renderComponent(ComponentClass, props = {}, appState = {}) {
const componentInstance = TestUtils.renderIntoDocument(
<Provider store={createStore(reducers, appState)}>
<ComponentClass {...props} />
</Provider>
);
// produces html
return $(ReactDOM.findDOMNode(componentInstance));
}
//build a helper for simulating events
// $.fn allows you to add a custom function to your jquery library
$.fn.simulate = function(eventName, value) {
if (value) {
// `this` allows you to access the object appended to
// `val()` is a jquery function that sets the value of selected html element
this.val(value);
}
// the [] are object method selectors, which allow you to access e.g. Simulate.change
TestUtils.Simulate[eventName](this[0]);
};
// set up chai jquery
chaiJquery(chai, chai.util, $);
export {renderComponent, expect};
It seems that react-router assumes navigator is in the global scope.
To resolve this error, you should add navigator to the global scope in your test setup phase:
global.navigator = {
userAgent: 'node.js'
};
I am evaluating angular 2.0 beta (with typescript) and tried to include some libraries via the module system. But somehow this does not work for c3.js / nv.d3.js.
Can anyone bump me into the right direction on how to c3.js / nv.d3.js to work?
tsconfig.json has "module": "system" (recommended by Angular 2.0)
tsconfig.json has "allowSyntheticDefaultImports": true (allows synthetic default import of d3.js)
import d3 from 'd3' works
import c3 from 'c3' does not work
import nv from 'nvd3' does not work
The c3.js site says import via AMD and require.js is possible.
The system.js site says it can import AMD modules as well
I am no JS pro, but there is no export statement in c3.js / nv.d3.js file, also there is no typescript definition in tsd. I'd create one and share it, but am not familiar enough with the concepts needed.
Seems I have to wait for the library developers to add a .d.ts declaration or add an export. Possible solutions for the meantime seem to be:
this:
Load "Vanilla" Javascript Libraries into Node.js
or: just declare c3 / nv and assume it's there at runtime
add to index.html: <script src="libs/c3.js"></script>
and in typescript: declare var c3;
add to index.html: <script src="libs/nv.d3.js"></script>
and in typescript: declare var nv;
I'm using Angular2 2.0.0-beta.17 and in a similar situation, building a proof of concept app with graphs and charts.
First, I imported the libraries using npm.
Next, these libraries are untyped Javascript but we can do something about that. if you are using Typings (and I recommend it) you can add these definitions to your typings.json (mine are under ambient):
"d3": "github:DefinitelyTyped/DefinitelyTyped/d3/d3.d.ts",
"nvd3": "github:DefinitelyTyped/DefinitelyTyped/nvd3/nvd3.d.ts",
"c3": "github:DefinitelyTyped/DefinitelyTyped/c3/c3.d.ts
I also had trouble importing. So, as a workaround I declared them:
declare var d3, nv: any;
Also, have a look at Krispo's ng2-nvd3 project which supplies an nvd3 component for Angular2
This project only worked for after I made the declarations changes.
I hope this helps -- I'm learning Angular2 myself so if anyone has some best practices, please share. The "declare... any" workaround does not seem optimal.
Thanks,
Cody
Assuming you are installing nvd3 as an npm package.
In the file where you bootstrap your app module do :
import 'nvd3/build/nv.d3';
import {enableProdMode} from '#angular/core';
import {platformBrowserDynamic} from '#angular/platform-browser-dynamic';
import {AppModule} from './app';
declare var process: any;
if (process.env.NODE_ENV === 'production') {
enableProdMode();
} else {
}
platformBrowserDynamic().bootstrapModule(AppModule);
And in the component .ts file do :
declare var nv:any;
This is how I implemented c3 chart in Ionic 2 -- similar to what Rob mentioned earlier :
Include the following links to index.html
<link rel="stylesheet" type="text/css" href="assets/js/c3.min.css">
<script type="text/javascript" src="assets/js/d3.min.js"></script>
<script type="text/javascript" src="assets/js/c3.min.js"></script>
Below is the implementation in the .ts file:
import {Component} from '#angular/core';
declare var c3;
declare var d3;
#Component({
templateUrl: 'graph.html'
})
export class GraphC3 {
constructor() {
}
ngOnInit() {
let chartoutput = c3.generate({
bindto: '#chart',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
]
}
});
}
}
In your graph.html file includes
<div id="chart"></div>
Hi I'm using dojo in amd mode for my main app (html page). I would like to create a module that references d3 library to create some charts. I'm having trouble creating this module -- what I've got so far for the module (a javascript file) is this:
define(["d3"], function (d3) {
return {
setd3ChartData: function () {
//this function can be called from my main app
//but d3 isnt linked to the d3 js library
}
}
});
in my main app I've got a link to the d3 libary in a script tag
How can I get this script link into the module? I can access d3 library just fine from main app
Thanks
Pete
When you want to use D3 with Dojo you probably first want to define the D3 package in your Dojo config. For example (when using a CDN):
<script type="text/javascript">
var dojoConfig = {
async: true,
parseOnLoad: true,
packages: [{
name: "d3",
location: "http://cdnjs.cloudflare.com/ajax/libs/d3/3.4.6/"
}]
}
</script>
Then you can use D3 by using:
require([ "d3/d3" ], function(d3) {
// Do stuff with "d3"
});
The reason you have to use "d3/d3" and not just "d3" is that the part before the / indicated the package name, in this case it's d3 (which we configured using dojoConfig).
The second part is the actual file, or in this case d3.js.
I also made a JSFiddle to show a working example of D3 loaded using the AMD loader. In that example I placed the Dojo configuration under the Fiddle options, but the setup is the same.
I also renamed the callback to d3Lib, because D3 by defaults creates the d3 global variable and now you can clearly see it's working with AMD.
If you want to use the minified version you can load "d3/d3.min".