Using RequireJS to load dojo modules - javascript

I am hosting ArcGIS JS API 4.1 locally in my project, so I have build the esri componenet and I have added the path in my requireJS config file. I also wanted to build the dojo folder, so basically build it to a single output file. But when I add the dojo modules using requireJS bundles I get an error in the esri file that e is not a function(…). The line of code that it appears on is:
define("dojo/_base/config", ["../has", "require"], function(e, t) {
var r = {};
if (e("dojo-config-api")) { ... } //e is undefined.
I get that the error means dojo/has is undefined but I don't understand why. I tried using dojo/has in my project and it is not undefined but in the esri file it says its undefined. Does anybody know how I can fix this.
This is requireJS config file:
requirejs.config({
paths: {
"jquery": 'https://code.jquery.com/jquery-3.1.0.min',
'esri/moment': 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment',
"esri": "../lib/arcgis-js-api-4/main",
"dojo": "../lib/arcgis-js-api-4/dojo-lib",
"dojox": 'http://js.arcgis.com/4.1/dojox',
"dijit": 'http://js.arcgis.com/4.1/dijit'
},
bundles: {
"esri": ["esri/Color",...],
'dojo': ['dojo/has', 'dojo/domReady',...]
},shim: {
"esri": {
deps: ["esri/moment", "dojo", "dojox", "dijit"]
}
}
});
This is the config for the dojo build:
var profile=(function(){
return {
basePath: "./",
releaseDir: "./",
releaseName: "dojoLib",
action: "release",
cssOptimize: 'comments',
layerOptimize: false,
packages:[{
name: "dojo",
location: "src/dojo"
}],
layers:{
"dojo/dojoLib": {
include: ["dojo/dojo", "dojo/i18n", "dojo/domReady", 'dojo/has', 'dojo/request', 'dojo/request/xhr',
'dojo/request/util', 'dojo/request/watch', 'dojo/io/script', 'dojo/io/iframe', 'dojo/query'],
customBase: true,
boot: false
}
}
};
})();

Related

How to Polyfill node core modules using vite

It seems that vite does not do automatic polyfills anymore - vite 4.0.0
How do you guys go about this? I have tried multiple variations of what I could find over the internet and none of them seems to be solid.
✘ [ERROR] The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_buffer.js" cannot be marked as external
✘ [ERROR] The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_virtual-process-polyfill_.js" cannot be marked as external
Build failed with 2 errors:
error: The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_buffer.js" cannot be marked as external
error: The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_virtual-process-polyfill_.js" cannot be marked as external
my config
// yarn add --dev #esbuild-plugins/node-globals-polyfill
import { NodeGlobalsPolyfillPlugin } from "#esbuild-plugins/node-globals-polyfill";
// yarn add --dev #esbuild-plugins/node-modules-polyfill
import { NodeModulesPolyfillPlugin } from "#esbuild-plugins/node-modules-polyfill";
// You don't need to add this to deps, it's included by #esbuild-plugins/node-modules-polyfill
import rollupNodePolyFill from "rollup-plugin-node-polyfills";
export default {
resolve: {
alias: {
// This Rollup aliases are extracted from #esbuild-plugins/node-modules-polyfill,
// see https://github.com/remorses/esbuild-plugins/blob/master/node-modules-polyfill/src/polyfills.ts
// process and buffer are excluded because already managed
// by node-globals-polyfill
util: "rollup-plugin-node-polyfills/polyfills/util",
sys: "util",
events: "rollup-plugin-node-polyfills/polyfills/events",
stream: "rollup-plugin-node-polyfills/polyfills/stream",
path: "rollup-plugin-node-polyfills/polyfills/path",
querystring: "rollup-plugin-node-polyfills/polyfills/qs",
punycode: "rollup-plugin-node-polyfills/polyfills/punycode",
url: "rollup-plugin-node-polyfills/polyfills/url",
string_decoder: "rollup-plugin-node-polyfills/polyfills/string-decoder",
http: "rollup-plugin-node-polyfills/polyfills/http",
https: "rollup-plugin-node-polyfills/polyfills/http",
os: "rollup-plugin-node-polyfills/polyfills/os",
assert: "rollup-plugin-node-polyfills/polyfills/assert",
constants: "rollup-plugin-node-polyfills/polyfills/constants",
_stream_duplex: "rollup-plugin-node-polyfills/polyfills/readable-stream/duplex",
_stream_passthrough: "rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough",
_stream_readable: "rollup-plugin-node-polyfills/polyfills/readable-stream/readable",
_stream_writable: "rollup-plugin-node-polyfills/polyfills/readable-stream/writable",
_stream_transform: "rollup-plugin-node-polyfills/polyfills/readable-stream/transform",
timers: "rollup-plugin-node-polyfills/polyfills/timers",
console: "rollup-plugin-node-polyfills/polyfills/console",
vm: "rollup-plugin-node-polyfills/polyfills/vm",
zlib: "rollup-plugin-node-polyfills/polyfills/zlib",
tty: "rollup-plugin-node-polyfills/polyfills/tty",
domain: "rollup-plugin-node-polyfills/polyfills/domain",
},
},
optimizeDeps: {
esbuildOptions: {
// Node.js global to browser globalThis
define: {
global: "globalThis",
},
// Enable esbuild polyfill plugins
plugins: [
NodeGlobalsPolyfillPlugin({
process: true,
buffer: true,
}),
NodeModulesPolyfillPlugin(),
],
},
},
build: {
rollupOptions: {
plugins: [
// Enable rollup polyfills plugin
// used during production bundling
rollupNodePolyFill(),
],
},
},
};
I encountered the same issue "cannot be marked as external" when working with the bip39 package and getting error because of buffer not defined. I tried many stuffs so not sure how what I solved, but here is my configuration (working with svelteKit):
In vite.config.js:
import { sveltekit } from '#sveltejs/kit/vite';
import type { UserConfig } from 'vite';
const config: UserConfig = {
plugins: [sveltekit()],
resolve: {
alias: {
// polyfills
Buffer: 'vite-compatible-readable-buffer',
stream: 'vite-compatible-readable-stream',
util: 'rollup-plugin-node-polyfills/polyfills/util',
}
}
};
export default config;
In layout.ts:
import { Buffer as BufferPolyfill } from 'buffer'
declare var Buffer: typeof BufferPolyfill;
globalThis.Buffer = BufferPolyfill
In app.html:
<script>
/**
* this is a hack for error: global is not defined
*/
var global = global || window
</script>
I hope it helps. I'm new to svelte and I don't 100% know what I'm doing :p

dojo build nls path and data

I added a new layer in dojo build config as below:
releaseDir: "./my-build",
layers: {
"myLib": {
include: [
"myFile1",
"myFile2"
]
}
}
After build, nls created under my-build folder, and include all locale files
my-build/
-myLib.js
-nls
--myLib_en-us.js
In the html file, my dojoConfig is:
var dojoConfig = {
async: true,
cacheBust: false,
paths: {
"ah": "/hm-webapp/resources/scripts/ah",
"i18n": '/hm-webapp/resources/i18n'
},
baseUrl: "/hm-webapp/resources/scripts/dojo/",
locale: ""
};
and I am including my layer via a script tag:
<script src="/my-build/myLib.js">
</script>
But there is a
404 error for myLib_en-us.js
It seems that dojo automatically load nls files, but the request path is like this
--/nls/myLib_en-us.js
There is no subpath "my-build" for the nls request.
My question is how to change the nls path to the build path.
Thanks.

RequireJs r.js load !tpl files error

I'm using requireJs with uderscore and tpl , I've changed the default file ending from .html to .tpl .
Now if I try to optimize my app i got the following error
Tracing dependencies for: app
Error: Error: Loader plugin did not call the load callback in the build:
tpl:
tpl!module/home/template/home_unnormalized2
tpl!module/home/template/home
/*
more templates
*/
Module loading did not complete for: app, /* failed for all modules */
at Function.build.checkForErrors (/usr/local/lib/node_modules/requirejs/bin/r.js:28424:19)
it seems like that r.js can't handle the .tpl or !tpl ending/beginning.
my build js
({
baseUrl: "js/lib",
appDir: "..",
dir: "dist",
tpl: {
extension: '.tpl' // default = '.html'
},
modules: [
{ name: "app" }
],
paths: {
app: '../app',
underscore: 'underscore',
text: 'text',
tpl: 'tpl',
//Module
home : '../module/home/home',
},
shim : {
}
})

Grunt build not exposing the globals I need

When I run my project locally with my grunt:server task, the project works as I expect. However, after building which takes all the vendor code and puts it into one file, two of my needed module aren't avialable, and the project doesn't work.
Here is my requirejs configuration:
requirejs.config
baseUrl: './js'
shim:
'underscore':
exports: '_'
'backbone':
deps: ['underscore', 'jquery']
exports: 'Backbone'
'stack':
deps: ['d3.global']
exports: 'stack'
'highlight':
exports: 'hljs'
paths:
'underscore': '../components/underscore/underscore'
'backbone': '../components/backbone/backbone'
'jquery': '../components/jquery/jquery'
'd3': '../components/d3/d3'
'd3.global': '../components/d3.global/d3.global'
'stack': '../components/stack/stack'
'highlight': '../components/highlightjs/highlight.pack'
require ['app/vendors'],->
console.log("Backbone", Backbone)
console.log("_", _)
console.log("$", $)
console.log("d3", d3)
console.log("stack", stack)
console.log("hljs", hljs)
app/vendors looks like
define [
'underscore'
'jquery'
'backbone'
'text'
'd3.global'
'stack'
'highlight'
], ->
When I run the project locally via grunt, I see all the globals printed out. However, when I build the project, Backbone Underscore and JQuery print out, while stack fails (hljs is also not available, and if I remove stack from app/vendors, it doesn't fix highlight, so its probably not an order thing).
the requirejs optimizer is called with the following configuration:
requirejs:
compile:
options:
baseUrl: 'js/'
appDir: './<%= yeoman.tmp_dist %>/'
dir: './<%= yeoman.dist %>/'
wrap: true
removeCombined: true
keepBuildDir: true
inlineText: true
mainConfigFile: '<%= yeoman.tmp_dist %>/js/main.js'
# no minification, is done by the min task
optimize: "none"
modules: [
{ name: 'app/vendors', exclude: [] }
{ name: 'app/app', exclude: ['app/vendors'] }
{ name: 'main', exclude: ['app/app', 'app/vendors'] }
Could there be something wrong with the stack and highlight files that I need to fix in order to make requirejs optimization and uglify work with them?
I installed highlightjs via bower by adding "highlightjs": "~8.0" to my bower.json file and running bower install. I downloaded stack.js from mbostock's stack project. I'm using v0 at the moment, with minor changes to make it work in this project. The source for all these are in the components directory of my github project.
BOUNTY If anyone is willing to clone the repo themselves, and try running the project with grunt server and grunt build to help me track down the problem, I'd greatly appreciate it. At the moment I have the vendor scripts in the github repo itself, so all you should need is compass and bower to run it.
This is due to wrap: true in the r.js config. Here's a simple configuration that isolates the issue:
main.js
define([ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
legacy.js
var globalThing = { foo: 1, bar: 2 };
build.json
{
"name": "main",
"optimize": "none",
"out": "main-built.js",
"shim": { "legacy": { "exports": "globalThing" } },
"wrap": true
}
Let's run r.js (r.js -o build.json) and consider the result (formatted by me):
(function() { // this immediately-invoked function expression (IIFE)
// is here because r.js has "wrap: true" in the config
var globalThing = { foo: 1, bar: 2 };
// code generated from the "shim" entry in the config
define('legacy', function(global) {
return function() {
var ret, fn;
// since global.globalThing is undefined,
// that's where it goes wrong
return ret || global.globalThing;
};
}(this));
define('main', [ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
})(); // end of the IIFE
As you can see from the code above, globalThing isn't global any more. The same happens with the stack and highlight libraries in your project as they use var and function declarations to define their globals.
To tackle this issue, we have a couple of options. The first is to consider whether you really need wrap: true in the config. If you drop it, the globals will get global again and everything should start working as expected. The second option is to try adding wrapShim: true to the config. You can read about nuances of using this option here. If we try it with our sample configuration, we'll get something like this:
(function() {
(function(root) {
define('legacy', [], function() {
return function() {
var globalThing = { foo: 1, bar: 2 };
return root.globalThing = globalThing;
}.apply(root, arguments);
});
})(this);
define('main', [ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
})();
Looks good to me.

Is there a way to build a Dojo module that includes a single file from the package location?

I have the following build profile for a small app:
var profile = (function(){
var copyOnly = function(filename, mid){
/* ..snip.. */
};
return {
basePath: "../../src",
releaseDir: "../dist",
releaseName: "lib",
action: "release",
packages: [
'dojo',
'dijit',
//'dojox',
'amd',
{
name: 'lodash',
location: 'lodash',
trees: [
[".", ".", /(\/\.)|(~$)|(vendor|test)/]
]
},
{
name: 'd3',
location: 'd3',
main: 'd3.min',
trees: [
[".", ".", /(\/\.)|(~$)|(src|lib|test)/]
]
},
{ name: 'app', location: 'app' }
],
layers: {
"dojo/dojo": {
include: [ "dojo/dojo", "amd/d3","amd/gmaps",
"app/main", "app/run" ],
customBase: true,
boot: true
}
},
resourceTags: {
/* ..snip.. */
}
};
})();
The problem is this: all I need is the lodash.min.js file to be processed by the Dojo build system. Unfortunately, when you include a package definition in your profile, the build system looks at all files in the relevant directory using an implicit trees value. You can overwrite it (as I have done here) and add some ignore directives, but this is ugly and leaves you open to missing something of. What I'd like to do is affirmatively indicate precisely which file(s) that I'm interested in processing for my build process.
Does Dojo allow you to do this? The documentation is a little scant in this area, but if you can help me find a resource that explains this more clearly, that would be great!
As of 1.9 at least, I believe this can be done:
// ... snip ...
{
name:'lodash',
location:'lodash',
trees:[],
dirs:[],
files:[
["lodash.min.js"]
]
},
This explicitly lists the files, while also squashing implicit tree and directory discovery.
My belief here is based on a cursory review of util/build/discover.js -- but as I read the documentation files only should be supported.

Categories