I'm trying to import a package that I've written into another package that I've written.
Pre-Babel Loader
class TestClass {
constructor() {
// Load flags on import here
console.log("TESTING CONSTRUCTOR");
}
log(message) {
console.log("TESTING LOG");
}
}
export default new TestClass();
Post Babel Loader
var TestClass = function () {
function TestClass() {
_classCallCheck(this, TestClass);
// Load flags on import here
console.log("TESTING CONSTRUCTOR");
}
_createClass(TestClass, [{
key: "log",
value: function log(message) {
console.log("TESTING LOG");
}
}]);
return TestClass;
}();
exports.default = new TestClass();
The import itself is simply a import TestClass from 'testclass-js'. However, every single time I'm trying to load it I get a "Darklaunch is not defined" error, and can't call any of the methods of the class.
I'm wondering what I've done wrong here.
If you're trying to import the ES5/commonjs version, you'll need to import 'yourmodule'.default; This change came in around babel 6
Babel 6 changes how it exports default
Read more on the original issue: https://github.com/babel/babel/issues/2212
If your package contains both an es5 and es6+ version, you can point to the es6 version in the module key in package.json and webpack/rollup will pick that up and bundle it instead of the commonjs version
Related
How to include functions in namespace / module when don't have module?
example: I have a namespace:
namespace Java {}
in typescript, usually when we need a function in namespace or module, we add 'export':
namespace Java {
export function version() {
return "java8";
}
}
namespace JavaScript {
function JavaVer() {
return Java.version();
}
}
But if I set module to none:
// tsconfig
"module": "none",
If module is none, I cannot use import / export:
website/sourcecode/main.ts:17:21 - error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'.
17 export function version() {}
so what can I do?
image:
You can use a plain object:
TS Playground
const Java = {
version () {
return "java8";
},
};
const JavaScript = {
JavaVer () {
return Java.version();
},
};
const vJ = Java.version(); // string
const vJS = JavaScript.JavaVer(); // string
console.log(vJ === vJS); // true
It was answered in here: It's actually "can't have any imports or exports at the top level". Imports and exports inside namespaces are fine because they don't export anything from .ts file at runtime, and as long as file remains 'not a module' module=None works fine. Long explanation here
Im bundling together the following files contents:
a.js:
class BaseC {
doIt(){
console.log(this);
}
}
class A extends BaseC{
}
b.js:
class B extends BaseC{
}
var b = new B()
b.doIt();
These are bundled in a final app.bundle.js. When running it i get : "Uncaught ReferenceError: BaseC is not defined". This is very odd to me as i can see it as defined first and foremost in the app.bundle.js prior to the rest of the classes as follows:.
var BaseC = function () {
function BaseC() {
_classCallCheck(this, BaseC);
}
_createClass(BaseC, [{
key: "doIt",
value: function doIt() {
console.log(this);
}
}]);
return BaseC;
}();
Any clues?
P.S: Im not using the require/import system. I know this is how webpack is normally used but what im doing is providing an array with all the js files i want bundled to webpack using the glob module and expected that with such a simple example, it should work.
Try exporting the class from a.js:
export class BaseC { ...
and importing it into b.js:
import {BaseC} from './a.js'
...
I've made some extensions to the Date prototype like:
interface Date {
YearsFromToday(): number;
}
Date.prototype.YearsFromToday = function (): number {
// implementation
}
I'm using the ionic2 tutorial --v2 template, which is a pretty standard layout - app.html, app.ts, app.module etc.
I was wondering if there was an easy way to have this declared globally. I'm not sure exactly where to put this in the project?
Put your monkey patch code in a file.
You might call it monkey-patch-date.ts, for example:
monkey-patch-date.ts
interface Date {
YearsFromToday(): number;
}
Date.prototype.yearsFromToday = function (): number {
// implementation
}
and then import it in main.ts or whatever your entry module is:
main.ts
import './monkey-patch-date';
Alternately. You can make it a module that exports its monkey-patcher if you want to be extra explicit to call out that you are doing something dangerous.
monkey-patch-date.ts
declare global {
interface Date {
yearsFromToday(): number;
}
}
export default function () {
Date.prototype.yearsFromToday = function (): number {
// implementation
};
}
And import it like
main.ts
import monkeyPatchDate from './monkey-patch-date';
monkeyPatchDate();
Another alternative, especially useful for library authors is to allow monkey-patching but not require it while still exposing the functionality.
Here is an example:
date-augmentations/index.ts
export function yearsFromToday(date: Date): number {
// implementation
}
date-augmentations/monkey-patch.ts
import {yearsFromToday} from './index';
declare global {
interface Date {
yearsFromToday(): number;
}
}
Date.prototype.yearsFromToday = function() {
return yearsFromToday(this);
}
Now a consumer can either monkey patch the Date prototype by running
import 'date-augmentations/monkey-patch';
Can access the functionality by the export without monkey patching anything
import {yearsFromToday} from 'date-augmentations';
const date = new Date('12-12-2023');
const yft = yearsFromToday(date);
console.log(yft); // prints 6
I'm trying to run an express app in ES6. I'm using the following workflow:
Transpile ES6 to ES5 using the following gulp task (with "es2015" and "stage-0" presets in .babelrc):
import gulp from 'gulp';
import gulpBabel from 'gulp-babel';
import sourcemaps from 'gulp-sourcemaps';
gulp.task('babel', () => {
gulp.src([
'someClass.js',
'app.js'
], {base: './', dot: false})
.pipe(sourcemaps.init())
.pipe(gulpBabel())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./dist'));
});
Which seems to be working fine.
Run node dist/app.js.
The following code is in someClass.js:
export default class SomeClass {
someMethod() {
return 1 + 1;
}
}
Finally, the following code is in app.js:
import SomeClass from './someClass';
//express config
console.log(SomeClass);
console.log(SomeClass.someMethod);
Which logs:
[Function: SomeClass]
undefined
Here is the relevant transpiled code:
dist/app.js
var _someClass = require('./someClass');
var _someClass2 = _interopRequireDefault(_someClass);
console.log(_someClass2.default);
console.log(_someClass2.default.someMethod);
dist/someClass.js
var SomeClass = function () {
function SomeClass() {
_classCallCheck(this, SomeClass);
}
_createClass(SomeClass, [{
key: "someMethod",
value: function someMethod() {
return 1 + 1;
}
}]);
return SomeClass;
}();
exports.default = SomeClass;
Why is someMethod undefined?
Because someMethod is a instance method. You need to instantiate the class with new to use the method.
const something = new SomeClass();
something.someMethod();
If you want to use the method without instantiating the class, you can define it as a static method.
export default class SomeClass {
static someMethod() {
return 1 + 1;
}
}
SomeClass.someMethod();
In the comment above, you said that you want to use it as a callback. To use it as a callback, you may want to bind a context to the method if you use this keyword in the method. Otherwise, the this keyword doesn't point to the instance when it's called as a callback function.
var something = new SomeClass();
element.addEventListener('click', something.someMethod.bind(something));
// or
element.addEventListener('click', (event) => something.someMethod(event));
I am looking to create a Modules system within my Application. I'm unsure on how to implement the following:
Module 1
class SomethingModule {
}
export default SomethingModule;
Module 2
class SomethingElseModule {
}
export default SomethingElseModule;
Module Loader
class ModuleLoader {
load(module) {
// "module" could be "Something" which should create a
// new instance of "SomethingModule"
module = module + 'Module';
// Require and create an instance of "module"
}
}
export default ModuleLoader;
Main File
var ModuleLoader = require('./ModuleLoader');
var loader = new ModuleLoader();
loader.load('SomethingElse');
I'm pretty new to modularised JavaScript and have no idea if this is even possible/feasible. If not, is there a way of doing this you'd suggest without polluting the global namespace and referencing window[moduleName]?
If I understand well your problem, you can create a Map and load your module in there:
class ModuleLoader {
constructor() {
this._modules = new Map();
}
load(module) {
// you should check if the module exist in a good world to not get any error
// and probably adjust the path of what you are requiring
this._modules.set(module, new require(`${module}Module`));
}
getModuleByName(name) {
return this._modules.get(name);
}
}
Edit: To make it work with browserify, you will need to have this list of all the modules somewhere. You can create a separate file ModuleBag like this:
//moduleBag.js
import yourModule from './yourModule';
import yourSecondModule from './yourSecondModule';
var map = new Map();
map.set('yourModule', yourModule);
map.set('yourSecondModule', yourSecondModule);
export default class map;
//moduleLoader.js
import moduleBag from './moduleBag';
class ModuleLoader {
constructor() {
this._modules = new Map();
}
load(module) {
var mod = moduleBag.get(module);
this._modules.set(module, new mod());
}
getModuleByName(name) {
return this._modules.get(name);
}
}
or just put it in the same file.
With this, browserify will be able to load all the necessary files.