Unable to find Blockly Generator function in Angular application - blockly

I am trying to build a Blockly Application using Angular. I installed Blockly using npm . I also added the following scripts in angular.json
"scripts": [
"node_modules/blockly/blockly_compressed.js",
"node_modules/blockly/blocks_compressed.js",
"node_modules/blockly/python_compressed.js",
"node_modules/blockly/msg/en.js"
]
Though i can use import * as Blockly from 'blockly' to import blockly in the application and use other functions, I am not able to find Generator functions like Blockly.Python['text_indexOf']
I am using blockly: ^3.20200625.2 and #angular/cli: ~9.1.0 versions.
Am i missing something. Can anyone help me with this issue?

I've had the same problem with electron+angular app building, the next solution had helped me.
Blockly's reference says that Python's generator class should be included with file python_compressed.js right after blockly_compressed.js. So I need to include these files.
First I've used copy-webpack-plugin to copy needed files from Blockly's install directory node_modules/blockly to assets/js:
var CopyPlugin = require('copy-webpack-plugin');
module.exports = {
...
plugins: [
...
new CopyPlugin([
{
from: 'node_modules/blockly/blockly_compressed.js',
to: 'assets/js/[name].[ext]'
},
{
from: 'node_modules/blockly/blocks_compressed.js',
to: 'assets/js/[name].[ext]'
},
{
from: 'node_modules/blockly/python_compressed.js',
to: 'assets/js/[name].[ext]'
},
{
from: 'node_modules/blockly/msg/en.js',
to: 'assets/js/msg/[name].[ext]'
},
]),
...
]
...
}
After I've added scripts calling from js/assets directly from index.html's bottom:
<!DOCTYPE html>
<html>
<head>...</head>
<body><app-root>...</app-root></body>
<script src="assets/js/blockly_compressed.js"></script>
<script src="assets/js/blocks_compressed.js"></script>
<script src="assets/js/python_compressed.js"></script>
<script src="assets/js/msg/en.js"></script>
</html>
After webpack build check python's generator in console:
> typeof Blockly.Python
< "object"

Related

install FullCalendar via NPM to laravel project

I am still new to Laravel and web packs.
I am trying to install FullCalendar via NPM into my Laravel project - Previously I have been working with includes from cdnjs, but I want to learn the other way. What I have done so far is:
https://fullcalendar.io/docs/initialize-es6
npm install #fullcalendar/core #fullcalendar/daygrid #fullcalendar/timegrid #fullcalendar/list
Then I updates my app.js in Laravel to
require('./bootstrap');
require('fullcalendar');
import { Calendar }from '#fullcalendar/core';
import dayGridPlugin from '#fullcalendar/daygrid';
import listPlugin from '#fullcalendar/list';
I also updates app.css
#tailwind base;
#tailwind components;
#tailwind utilities;
#fullcalendar/core/main.css;
#fullcalendar/daygrid/main.css;
#fullcalendar/timegrid/main.css;
#fullcalendar/list/main.css;
Then I ran
npm run dev
In blade file, I re-use the code from when I was working with script file from cdnjs. I added the updated app.js file, which was compiled through npm run dev
<div id="calendar"></div>
<script>
$(document).ready(function() {
// page is now ready, initialize the calendar...
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'dayGrid','List'],
header: {
left: 'prev,next today',
right: 'dayGridWeek,listWeek'
},
defaultView: 'dayGridWeek',
contentHeight: 'auto',
events : [
#foreach($events as $event)
{
title : '{{ $event->title }}',
start : '{{ $event->start_event }}',
},
#endforeach
]
});
calendar.render();
});
</script>
<script src="{{ asset('js/app.js') }}"></script>
The error I get is:
I don't understand why, and I have been playing around with app.js and re-compiling it a bunch of times and changing order of my code.. nothing works. What am I missing?
I had similar issue, made mine work this way:
//app.js
...
import { Calendar } from '#fullcalendar/core';
window.Calendar = Calendar;
import interaction from '#fullcalendar/interaction';
window.interaction = interaction;
import dayGridPlugin from '#fullcalendar/daygrid';
window.dayGridPlugin = dayGridPlugin;
import timeGridPlugin from '#fullcalendar/timegrid';
window.timeGridPlugin = timeGridPlugin;
import listPlugin from '#fullcalendar/list';
window.listPlugin = listPlugin;
...
Then, I use it on pages that require me to render fullcalendar like so:
//somescript.js
...
var calendar = new window.Calendar($('#calendar').get(0), {
plugins: [window.interaction, window.dayGridPlugin, window.timeGridPlugin, window.listPlugin],
selectable: true,
initialView: 'dayGridMonth',
eventBorderColor: 'white',
eventClick: info => { ... },
dateClick: info => { ... },
select: info => { ... }
...
});
calendar.render();
...
For styling,
//app.scss
// Variables
#import 'variables';
// Fullcalendar
#fullcalendar/core/main.css;
#fullcalendar/daygrid/main.css;
#fullcalendar/timegrid/main.css;
#fullcalendar/list/main.css;
Should this line:
var calendar = new FullCalendar.Calendar(calendarEl, {
Be changed to this:
var calendar = new Calendar(calendarEl, {
Thats what I gather from looking over https://fullcalendar.io/docs/initialize-es6
Here is a good example:
https://github.com/fullcalendar/fullcalendar-example-projects/blob/master/webpack/src/main.js

Bind dynamic Vue image src from node_modules

I' am creating a Vue component that shows an SVG image from my node modules based on a given image name or key (given by an API).
If I put the source image directly like ~cryptocurrency-icons/svg/color/eur.svg, the resource loads.
But if I try to compute it with the props or by the mounted method asigning it using :src="imageSource" it does not load.
I'm new to Vue so I don't know why is this happening? Should I use images downloaded in a public directory instead of the NPM package?
<template lang="html">
<img src="~cryptocurrency-icons/svg/color/eur.svg" alt="icon" />
</template>
<script lang="js">
export default {
name: 'crypto-icon',
props: ['currency'],
mounted() {
this.imageSource = `~cryptocurrency-icons/svg/color/${this.currency}.svg`
},
data() {
return {
imageSource: ""
}
},
methods: {
getImageResource(){
return `~cryptocurrency-icons/svg/color/${this.currency}.svg`
}
},
computed: {
}
}
</script>
<style lang="scss" scoped>
.crypto-icon {}
</style>
You are missing the require attribute. Vue Loader, does this automatically when it compiles the <template> blocks in single file components. Try with this:
require(`~cryptocurrency-icons/svg/color/${this.currency}.svg`)
You can read more here.
I've solved it by using a Vue plugin (see vue-cryptoicons), although hatef is right about using require for image resources, using it in directories under node_modules tries to find the full path
~cryptocurrency-icons/svg/color in ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"a7e19d86-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Wallet.vue?vue&type=template&id=7f1455a9&scoped=true&lang=html&
To install it, you can run: npm install --save ~cryptocurrency-icons/svg/color

require.js + cldrjs Why renaming a config paths entry break it?

Summary
The rename below (s/cldr/cldrjs) breaks load functionality.
require.config({
paths: {
- cldr: "./bower_components/cldrjs/dist/cldr"
+ cldrjs: "./bower_components/cldrjs/dist/cldr"
}
});
require([
- "cldr",
- "cldr/supplemental"
+ "cldrjs",
+ "cldrjs/supplemental"
], function( Cldr ) {
console.log( "Cldr instance", new Cldr( "en" ) );
}, function() {
Setup
Install libraries.
bower install cldrjs requirejs
You should get:
cldrjs /tmp/cldrjs
├── cldrjs#0.3.2 extraneous
└── requirejs#2.1.11 extraneous
Usage
Open index.html (available at https://gist.github.com/rxaviers/10194312). Require.js should load Cldr, and your console should log an instance of it, eg:
Cldr instance Object { attributes={...}, locale="en", supplemental=function(), more...}
Question
Why does the rename break it?
To make it easier for you, I've placed both main files (available at https://gist.github.com/rxaviers/10194312). Simply change the reference to test it.
--- a/index.html
+++ b/index.html
## -4,7 +4,7 ##
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body>
- <script data-main="main.cldr.js" src="bower_components/requirejs/require.js"></script>
+ <script data-main="main.cldrjs.js" src="bower_components/requirejs/require.js"></script>
</body>
</html>
Apendix
Piece of info worth knowing...
Header of cldr.js: (available at https://gist.github.com/rxaviers/10194312)
define(function() {
// implementation... Yeap, no dependencies.
})
Header of cldr/supplemental.js: (available at https://gist.github.com/rxaviers/10194312)
define(["../cldr"], function() {
// implementation... Dependency is the above cldr.js file.
})
https://github.com/jrburke/requirejs/issues/1084#issuecomment-40112805
I have chatted with #jrburke on IRC and he pointed out that
`../cldr’ is resolved relative to ‘supplemental’ as an ID first, which ends up with a ‘cldr’ in the ID, then that is converted to a path
but since that path already was used for a module called ‘cldrjs’ that is a problem, does not find a ‘cldr’ module in it
more in a bit after i set up the project
but i think the end result is that you will want to use either a map or packages config
Solution:
the general rule of thumb is: if the package only contains one JS module then paths config is good enough. If it contains multiple modules (as in this case) package config is usually a better fit
unless the package manager knows about front end modules
Thanks #jrburke

Load "on the fly" code with requirejs

I'm trying to create an online interactive js programming test-bed. I have a code window and a target iframe where the code gets loaded to execute. I wrap the code in html and load it into the iframe. The problem is that the code I want to be testing is normally loaded via requirejs using a data-main parameter. It appears that the code needs to be loaded from a separate file so that I can't include it in the html itself.
What works but doesn't help me is creating a file on the server to use as the target of the data-main parameter and sending html to the iframe that requires requirejs and then loads my code.
html:
<html>
....
<script type="text/javascript" src="lib/requirejs/require.js" data-main="src/requireConfigTest"></script>
....
</html>
contents of requireConfigTest.js:
/*globals require*/
require.config({
shim: {
},
paths: {
famous: 'lib/famous',
requirejs: 'lib/requirejs/require',
almond: 'lib/almond/almond',
'famous-polyfills': 'lib/famous-polyfills/index'
}
});
// this is the injection point where the dynamic code starts
define(function (require,exports,module) {
var Engine = require("famous/core/Engine");
var Surface = require("famous/core/Surface");
var mainContext = Engine.createContext();
var surface = new Surface({
size: [100, 100],
content: "Hello World",
classes: ["red-bg"],
properties: {
textAlign: "center",
lineHeight: "20px"
}
});
alert('hi');
mainContext.add(surface);
});
//this is the end of the dynamic code
This requires writing the dynamic code back to the server, not a reasonable solution. I'm trying to implement something like this...
html:
<html>
....
<script type="text/javascript" src="lib/requirejs/require.js"</script>
<script type="text/javascript">
/*globals require*/
require.config({
shim: {
},
paths: {
famous: 'lib/famous',
requirejs: 'lib/requirejs/require',
almond: 'lib/almond/almond',
'famous-polyfills': 'lib/famous-polyfills/index'
}
});
// this is the injection point where the dynamic code starts
define(function (require,exports,module) {
var Engine = require("famous/core/Engine");
var Surface = require("famous/core/Surface");
var mainContext = Engine.createContext();
var surface = new Surface({
size: [100, 100],
content: "Hello World",
classes: ["red-bg"],
properties: {
textAlign: "center",
lineHeight: "20px"
}
});
alert('hi');
mainContext.add(surface);
});
//this is the end of the dynamic code
</script>
This fails with the message:
Uncaught Error: Mismatched anonymous define() module: function
(require, exports, module) {...
My hope is to either find a way to reformat the code above in the second script tag or find a way to pass the actual contents of requireConfigTest.js via data-main instead of passing the name of the file to load.
Any help here would be greatly appreciated.
Since you are not actually defining a module with your define call, you could just use require:
require(["famous/core/Engine", "famous/core/Surface"], function (Engine, Surface) {
var mainContext = Engine.createContext();
// Etc...
You can think of define as being a require call which additionally defines a module. The way you are using define it is defining a module that does not have a name because you did not give it a name (which is generally the right thing to do) but it is not loaded from a .js file. When you don't give a name to a module as the first argument of define, RequireJS assigns a name from the .js file it loads the module from.
Another thing to keep in mind is that require schedules its callback for execution right away. (The callback is not executed right away but it scheduled for execution right away.) Whereas define does not schedule anything. It just records the callback and then when a require call (or something equivalent) requires it, the callback is executed.

How to write a lodash template loader for requirejs

I'm using a requirejs plugin to define "tmpl!" loader (not a jquery template, but a lodash template. The problem is that the text! loader is adding a ";" at the end of the template. This is being rendered and is breaking everything.
(function(global){
"use strict";
define({
load : function(name, require, load, config) {
var deps = [];
deps.push('text!' + name);
deps.push('underscore');
require(deps, function(source, _) {
var template = _.template(source);
load(template);
});
}
});
})(this);
How can I stop text! from adding a semi-colon? Or: is there a better way to do this?
Taking the questions in reverse order:
is there a better way to do this?
It seems there is an existing implementation of this, and you might want to consider using it rather than writing your own. Although the simple case is a small amount of code, there are a bunch of r.js optimizer-related things you might eventually need.
But regarding your implementation logic, I noticed that this similar project for Handlebars does not use the text! plugin but instead does its own XHR in the load() method. This is not explained, but he gives some guidance for adapting it to other templating languages. Note: the link came from this question where there is some other good discussion of the approach.
How can I stop text! from adding a semi-colon?
I tried your plug-in and did not get any added semicolons. Perhaps you could post more of the sample project and templates? Below is mine, with everything in one flat folder for simplicity:
require.js: latest from RequireJS site
domReady.js: latest from RequireJS site
text.js: latest from RequireJS site
lodash.js: latest from lodash site
tmpl.js: your example loader from the question
index.html:
<!DOCTYPE html>
<html>
<head>
<script src='require.js'></script>
<script>
requirejs.config({
map: {
'*': { 'underscore': 'lodash' }
}
});
require( [ 'underscore', 'tmpl!friend-template.htm', 'domReady!' ]
, function( _, friendTemplate ){
var friendsData = [{ name: 'Bob', age: 35 }, { name: 'Fred', age: 38 }];
document.body.innerHTML = friendTemplate( {friends: friendsData});
});
</script>
</head>
<body>
<!-- To be populated dynamically. -->
</body>
</html>
friend-template.htm:
<ul>
<% _.forEach(friends, function(friend) { %>
<li>
<span><%- friend.name %></span>
<span>( Age: <span class="value"><%- friend.age %></span> )</span>
</li>
<% }); %>
</ul>
I've created a loader specifically for Lo-Dash which you can see here:
https://gist.github.com/tbranyen/6821045
Note: I have no unit tests or assurances this free of bugs, but from my initial testing it appears to work fantastic.
This is better in a number of ways than requirejs-tpl which bakes in it's own implementation which is not exposed. It also requires a file extension and hardcoded path. Both of these are configurable in my code.
Edit: I've since released a project called lodash-template-loader which has tests. https://github.com/tbranyen/lodash-template-loader

Resources