ReferenceError when using require - javascript

I'm trying to create a wrapper as a React component for this DateTimePicker jQuery plugin. So far it's working, but I'm trying to set it's locale and to do that I need to import a specific file from the library.
I'm doing so at require('gijgo/js/messages/messages.pt-br'), however it throws an error ReferenceError: gj is not defined. The object gj is imported at require('gijgo/js/gijgo'); and I already tried doing something like this:
const gj = require('gijgo/js/gijgo');
window.gj = gj;
require('gijgo/js/messages/messages.pt-br')
Just like I did to import jQuery (the library gijgo uses it), but it didn't work.
This is my whole code:
import React from "react"
import $ from 'jquery'
import 'bootstrap';
import { TextInput } from '../Form/Form'
window.jQuery = $;
window.$ = $;
require('gijgo/js/gijgo');
require('gijgo/js/messages/messages.pt-br')
require('gijgo/css/gijgo.css');
export default class DateTimePicker extends React.Component {
componentDidMount() {
this.$dateTimePicker = $(this.dateTimePicker);
this.$dateTimePicker.on("change", this.props.onChange);
this.$dateTimePicker.datetimepicker({
locale: 'pt-br',
uiLibrary: 'bootstrap4',
format: 'dd-mm-yyyy HH:MM',
modal: true,
footer: true
});
}
componentWillUnmount() {
this.$dateTimePicker.destroy("datetimepicker");
}
render() {
return (
<TextInput {...this.props} ref={dateTimePicker => this.dateTimePicker = dateTimePicker}/>
)
}
}
Is there a way to "require something after something else fully loaded?". Am I missing something?
Note 1: yes, I know jQuery + React = bad, but I like this component and I'm porting an old project to React that uses this library, so I figure it would be nice to have it as a React component. My main goal however, is to have some Date Time Picker component that looks like gijgo's and works with React, so I'm open to suggestions.
Note 2: I'm using gijgo through npm (npm install gijgo --save)
Update 1
Note 3: I'm kinda new at React JS development and I'm not quite sure what I'm using for bundling, but the script that runs when I run npm start or yarn start is react-scripts start. Also, the error also shows __webpack_require__ and
779 | };
780 |
781 | // Execute the module function
> 782 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 783 |
784 | // Flag the module as loaded
785 | module.l = true;
Update 2
I've tried creating a separate file to import jQuery and setting it globally, so I could stop using require and use import instead. Still, I keep getting the same error.
Here's my jQuery.js file:
import jquery from 'jquery';
global.$= jquery;
global.jQuery = jquery;
and here's my updated imports:
(...)
import '../jQuery'
import 'gijgo/js/gijgo'
import 'gijgo/js/messages/messages.pt-br'
import 'gijgo/css/gijgo.css'
(...)
Update 3
It didn't work when I tried using gijgo from <script>, it said datetimepicker is not recognized. I must be doing something wrong, as I'm having a hard time trying to understand how to mix jQuery with React. I think gijgo is a good library and everything. But for this particular case I actually decided to use DateTimePicker from material-ui/pickers.

Related

What is the correct way to import esm/dist modules? (React/javascript)

So we're using the geist component library in our codebase. It's pretty much integrated into parts of our app and since this library is 250kb, it's impacting our page speed. To circumvent importing the entire module, the usual solution is just importing what you need and ideally, nothing should break and everything should work as expected.
import { CssBaseline } from "#npkn/geist-react"
Doing the above should work but adds 250kb to the bundle.
Another way to import a component would be to import the specific file. I get two options to import the component from either ESM or dist modules
import CssBaseline from "#npkn/geist-react/dist/css-baseline"
and
import CssBaseline from "#npkn/geist-react/esm/css-baseline/index"
I've tried doing both of these but webpack throws errors. I've tried importing named exports as well but even then it throws an error.
TypeError: _npkn_geist_react_dist_css_baseline__WEBPACK_IMPORTED_MODULE_0___default(...).flush is not a function
9 | static async getInitialProps(ctx) {
10 | const initialProps = await Document.getInitialProps(ctx)
> 11 | const styles = CssBaseline.flush()
| ^
12 |
13 | return {
14 | ...initialProps,
My question is am I doing the imports right or is there something I'm missing?
Thank you!
If anyone else comes across this question, please check out the bundle size example https://geist-ui.dev/en-us/guide/bundle-size. The example doesn't quite work but I found this work around https://spectrum.chat/geist-ui/react/minimize-build~d30af727-2b97-4d16-9357-9b4e5104fdc9
Instead of doing
import Button from '#geist-ui/react/esm/button'
do
import Button from '../../../../node_modules/#geist-ui/react/esm/button';
Reduced our bundle size significantly!

Using CKEditor5 Custom Build in Angular App

I'm building a sort of article editor, for this I'm using the Angular Integration for CKEditor5; following the documentation I can correctly use the ClassicEditor build with the ckeditor component.
These are my files:
import { Component, OnInit } from '#angular/core';
import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic';
#Component({
selector: 'app-edit-article',
templateUrl: './edit-article.component.html',
styleUrls: ['./edit-article.component.scss']
})
export class EditArticleComponent implements OnInit {
constructor() { }
public Editor = ClassicEditor;
articleForm: FormGroup;
ngOnInit() {
}
}
Template
<div class="row">
<div class="col-12">
<label for="">Content</label>
<ckeditor [editor]="Editor" id="editor" class="blue-scroll--light" formControlName="content"></ckeditor>
</div>
</div>
Unfortunately, the ClassicEditor build referenced in that guide does not include many plugins, so I'm trying to add some of them, like text alignment, font color, font size, etc.
It seems that I need to create a custom build which includes all of the desired features and then reference that build instead of the ClassicEditor in my typescript file if I understand correctly, so I went ahead and used their online builder to create a build with all the plugins already included, but after that I'm not sure how to proceed and the documentation isn't really clear.
As far as I understand, I need to add the build folder inside my Angular App and then import the ckeditor.js file in my component, like this:
import * as Editor from '../../../../../core/libs/ckeditor5/build/ckeditor';
and change the declaration of the Editor to use that import instead of the ClassicEditor, so:
public Editor = Editor;
However as soon as I make that change I'm no longer able to even run the app, since I get the following error:
ERROR Error: Uncaught (in promise): CKEditorError: ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated. Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-ckeditor-duplicated-modules
CKEditorError: ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated. Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-ckeditor-duplicated-modules
at Object.<anonymous> (ckeditor.js:5)
at Object.push../src/app/core/libs/ckeditor5/build/ckeditor.js (ckeditor.js:5)
at i (ckeditor.js:5)
at Module.<anonymous> (ckeditor.js:5)
at i (ckeditor.js:5)
at push../src/app/core/libs/ckeditor5/build/ckeditor.js (ckeditor.js:5)
at ckeditor.js:5
at ckeditor.js:5
at Object../src/app/core/libs/ckeditor5/build/ckeditor.js (ckeditor.js:5)
at __webpack_require__ (bootstrap:84)
at resolvePromise (zone.js:852)
at resolvePromise (zone.js:809)
at zone.js:913
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:30885)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at drainMicroTaskQueue (zone.js:601)
Again, the docs say it is due to multiple imports being made but I don't understand how since I'm only using the ckeditor.js file that comes in the build I just generated, which works fine if referenced in a plain HTML file.
Can someone provide an example on how to successfully make a Custom Build work in a Angular App?
After a while, I found that the problem seems to be that I had another build imported in a different module of my application.
So I was only using the custom build inside my EditArticle component by importing and using that file, but I also had other components on other modules that were importing and using the ClassicEditor build that I installed through NPM, which looks like it was causing the error.
The fix was not to remove the ClassicEditor package nor removing the import ClassicEditor statement, but just making sure that that specific import was not being used anywhere else in the app, since I guess during compilation Angular removes all unused imports.
Once I did this, the application ran fine with my custom build.
Just to clear it up, I can have these two imports on the same file or multiple components
import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic';
import * as Editor from 'src/app/core/libs/ckeditor5/build/ckeditor';
But I should only be using one of them on the entire app, so if I have an Editor on Component1 and on Component2, I can have both builds imported, but on the declaration of the Editor property I should only use one, and it should be the same one on every component the app uses, so:
This works
Component1
import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic';
import * as Editor from 'src/app/core/libs/ckeditor5/build/ckeditor';
public Editor = Editor;
Component2
import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic';
import * as Editor from 'src/app/core/libs/ckeditor5/build/ckeditor';
public Editor = Editor;
This WON'T work
Component1
import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic';
import * as Editor from 'src/app/core/libs/ckeditor5/build/ckeditor';
public Editor = Editor;
Component2
import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic';
import * as Editor from 'src/app/core/libs/ckeditor5/build/ckeditor';
public Editor = ClassicEditor;
You can of course just remove the unused build from the imports altogether and that'll work too. Just again, make sure you use the same build on all the application
console.log(this.ckEditorClassic.builtinPlugins.map( plugin => plugin.pluginName ));
}
This will give you the list of plugins in the custom build.
My sample has :
["Alignment", "AutoImage", "Autoformat", "Autosave", "BlockQuote", "Bold", "CodeBlock", "Essentials", "ExportPdf", "ExportWord", "FontBackgroundColor", "FontColor", "FontFamily", "FontSize", "Heading", "Highlight", "HorizontalLine", "Image", "ImageCaption", "ImageInsert", "ImageResize", "ImageStyle", "ImageToolbar", "ImageUpload", "Indent", "IndentBlock", "Italic", "Link", "List", "Markdown", "MathType", "MediaEmbed", "MediaEmbedToolbar", "PageBreak", "Paragraph", "PasteFromOffice", "SpecialCharacters", undefined, undefined, undefined, undefined, undefined, "Strikethrough", "Subscript", "Superscript", "Table", "TextTransformation", "WordCount"]
take the displayed list within [] and replace xxxx with it.
<ckeditor [config]="{toolbar:[xxxx] }"

How do I manually include "#material/drawer" into my component?

I am trying to manually include the #material/drawer npm package into my Ember app. I tried following this guide but I'm running into some weird errors in my Chrome dev console:
Uncaught SyntaxError: Unexpected token *
Uncaught ReferenceError: define is not defined
The first is from the imported node_modules/#material/drawer/index.js file and the second is from my generated shim.
My component code:
import Component from '#ember/component';
import { MDCTemporaryDrawer, MDCTemporaryDrawerFoundation, util } from '#material/drawer';
export default Component.extend({
init() {
this._super(...arguments);
const drawer = new MDCTemporaryDrawer(document.querySelector('.mdc-drawer--temporary'));
document.querySelector('.menu').addEventListener('click', () => drawer.open = true);
}
});
In my ember-cli-build.js:
app.import('node_modules/#material/drawer/index.js');
app.import('vendor/shims/#material/drawer.js');
My generated shim:
(function() {
function vendorModule() {
'use strict';
return {
'default': self['#material/drawer'],
__esModule: true,
};
}
define('#material/drawer', [], vendorModule);
})();
What exactly am I doing wrong? It almost seems as though raw ES6 code got imported rather than compiled into my JS build output.
I also read this SO post but there are too many answers and I'm not sure which to do. It seems this specific answer is what I'm trying to do but not verbatim enough.
Creating a shim only ensures that ember-cli gets an AMD module, which you then can import in your app files.
If the npm package needs a build or transpiling step beforhand, this won't work.
You need a way to get the package build within the ember-cli build pipeline.
Luckily there are addons which can take care of this for you: ember-auto-import and ember-cli-cjs-transform.
You may have also heard of ember-browserify, which does the same thing, but it's deprectaed in favor of ember-auto-import.
I'd suggest you try ember-auto-import:
ember install ember-auto-import
You then should be able to import as you tried:
import { MDCTemporaryDrawer, MDCTemporaryDrawerFoundation, util } from '#material/drawer';
No shim or app.import needed, as ember-auto-import will take care of this for you.

Custom Uppy Plugin

I'm trying to make a custom Uppy React plugin but I'm getting the following error
'TypeError: Cannot call a class as a function'
import Plugin from 'uppy/src/core/Plugin';
export default class DropZone extends Plugin {
}
I am then consuming the component as follows:
import React from 'react';
import Uppy from 'uppy/lib/core/Core';
import DropZone from '../DropZone';
const uppy = new Uppy({ debug: true });
uppy.run();
export default class FileManager extends React.Component {
render() {
return (<DropZone uppy={uppy} />);
}
}
I've cut down the code for simplicity. I looked at the implementation of the uppy DragDrop plugin and followed its implement but still get the same error.
Has anyone had experience writing a react plugin for Uppy? as I'm lost as to how I can resolve this error.
Thanks
I've successfully created a plugin using the following import statement:
import { Uppy, Plugin, PluginOptions, UppyFile } from "#uppy/core";
It's not clear from your question whether you're using the npm package or have downloaded manually, but in my case I installed Uppy using:
npm i #uppy/core
First of all, in your "DropZone" plugin, you'll need to implement at least the install() and uninstall() methods (those get called by uppy).
Second, if you want to tell uppy to use your plugin, you need to do something like:
const uppy =
new Uppy({ debug: true })
.use(DropZone)
.run();
I suggest simply looking at the source code for other plugins to understand how they work, there are different kinds of Plugins - Providers for files management, GUI plugins for display in the Dashboard, etc...
Hope this helps

correct ES6 import for adding moment precise range plugin

I'm using typescript within an angular 4 project and want to use moment-precise-range-plugin.
I've installed moment following https://momentjs.com/docs/#/use-it/typescript/ but i want to add the preciserange plugin http://momentjs.com/docs/#/plugins/preciserange/.
Install for Node.js for the preciserange plugin is at https://codebox.org.uk/pages/moment-date-range-plugin and specifies require('moment-precise-range-plugin'); but there is no Typescript install.
I've tried import { Moment } from 'moment-precise-range-plugin'; but get the following typescript error
Could not find a declaration file for module 'moment-precise-range-plugin'. 'c:/Users/[UserName]/app/node_modules/moment-precise-range-plugin/moment-precise-range.js' implicitly has an 'any' type. Try npm install #types/moment-precise-range-plugin if it exists or add a new declaration (.d.ts) file containing declare module 'moment-precise-range-plugin';'
Any ideas very much welcome!
I'm using the moment-precise-range-plugin in an Angular 4 project and was able to import it with:
import 'moment-precise-range-plugin';
I imported it after importing moment: import * as moment from 'moment';
One thing to note: my TS linter still warns me that preciseDiff() will cause problems, but it all runs just fine. Try that out and see if it works.
NOTE: I'm using Angular 10.
It works with me when import it as -> import 'moment-precise-range-plugin';
and add these 3 lines:
declare module 'moment' {
function preciseDiff(start: string | Date | moment.Moment, end: string | Date | moment.Moment, convertToObject?: boolean): any;
}
I fixed it by adding a definition file in src/typings.d.ts
import * as moment from 'moment';
export = moment;
declare module 'moment' {
interface Moment {
preciseDiff(start: string | Date | moment.Moment): string;
}
}

Categories

Resources