jQuery as AMD module and optimizing with r.js - optimization

Allright, he is the thing. I am using curl.js for my AMD loader, but i don't like much of "cram" because it needs to be run on unix and i am developing on Windows. So the r.js adapter for nodeJS from RequireJS library comes in mind, because node has already binary for Windows.
Now jQuery in current version (1.6.4) is not valid AMD module (coming in version 1.7) and there is dependencies in jQueryUI components, so i had to fake like this:
curl( [js!Core/jquery.js] )
.then( function() {
define('jquery', function() { return jQuery; });
})
My application is happy with this. However using r.js (version 0.26.0) fails on this part with following error:
Tracing dependencies for: boot
function (){return jQuery}
node.js:207
throw e; // process.nextTick error, or 'error' event on first tick
^
ReferenceError: jQuery is not defined
at eval at <anonymous> (r.js:7468:30)
at main (r.js:770:33)
at callDefMain (r.js:840:18)
This is my app.build.js
({
appDir: '../',
baseUrl: 'Scripts/',
paths: {
'link': '../../../Lib/#Javascript Libs/curl.js/src/curl/plugin/link.js'
},
dir: 'built',
optimize: 'none',
modules: [
{ name: 'boot' }
]
})
And here is complete boot.js for reference (coffeescript):
require([
'link!styles/main.css'
'js!Core/jquery.js!order'
'js!Core/underscore.js!order'
'js!Core/backbone.js!order'
]).then ->
define 'jquery', -> jQuery
.next(['Router/MainRouter'])
.then (MainRouter) ->
new MainRouter()
Backbone.history.navigate('home') unless Backbone.history.start(
pushState: false
)
Thank you in advance for any hint where the catch can be...

Correct. RequireJS uses a different syntax on its global requirejs() (aka require()) function. RequireJs also doesn't have the "js!" plugin built-in. You may have to include a path to it in your config. You could also use RequireJS's syntax for non-module javascript files.
Also: cram 0.2 will support Windows environments using Rhino. We're writing tests for cram 0.2 and will be releasing it shortly.
RequireJS syntax (remove js! prefix and include .js extension):
require([
'link!styles/main.css'
'order!Core/jquery.js'
'order!Core/underscore.js'
'order!Core/backbone.js'
], function (maincss, jQuery, underscore, backbone) {
// do something here
});

Related

Docusaurus getting mermaid up and running

[docusaurus] Newbie question: I am attempting to get mermaid up and running on my website, but am struggling to implement https://docusaurus.io/docs/markdown-features/diagrams. My docusaurus.config.js file is structured as follows:
const config = {
...
presets: [
...
],
themeConfig:
({
...
}),
}
module.exports = config;
Where should the block
markdown: {
mermaid: true,
},
themes: ['#docusaurus/theme-mermaid'].
be included in this structure?
I have attempted to include the stated block at all different points in the config.js file, but I either get a compile fail, or compile succeed, but no mermaid behaviour.
Thanks!
It is now working - I think the issue here was that the project I was attempting to use mermaid on was a 2.1.0 project. Once I updated it to 2.2.0 then things work as the documentation suggests.

What exactly is Vue's runtime-only build and how does it differ from compiler build?

I am getting this warning:
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
with my basic boilerplate code below. I understand it's blocking me from creating my Foo component like that but exactly does that mean and how does it different from another way of instantiating the Vue instance?
const Foo = {
template: `<div>xxx</div>`
}
const routes = [
{ path: '/foo', component: Foo },
{ path: '/', component: App}
]
const router = new VueRouter({
routes:routes
})
Vue.config.productionTip = false
new Vue({
router
}).$mount('#app')
Full build (i.e. "compiler-included")
Also known as the "full" build, "compiler-included" includes both compiler and runtime. The compiler is what allows using template strings like:
template: `<div>xxx</div>`
CDN: When using Vue through a CDN, e.g. <script src="https://unpkg.com/vue"></script>, it's typically the Full build (unless you specify otherwise).
Runtime-only
The alternative to template strings is the render function. If you used only these, you wouldn't need the compiler, and could use a runtime-only build:
render(h) {
return h('div', 'xxx')
}
Bundlers (e.g. Vue CLI): When you use a bundler like Vue CLI, it pre-builds your templates into render functions for you so that the compiler isn't needed in production. This allows for a runtime-only build.
The docs describe the runtime like this:
Runtime: code that is responsible for creating Vue instances, rendering and patching virtual DOM, etc. Basically everything minus the compiler.
So, the difference between the Full build and the Runtime-only build is the inclusion or exclusion of this template compiler.
The docs explain it this way:
If you need to compile templates on the client (e.g. passing a string to the template option, or mounting to an element using its in-DOM HTML as the template), you will need the compiler and thus the full build:
And there is this caveat to be aware of:
Since the runtime-only builds are roughly 30% lighter-weight than their full-build counterparts you should use it whenever you can
Also in the docs are configurations for using the full build with bundlers. In Webpack, for example, it's:
module.exports = {
// ...
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
}
}

Vue.js 3 extension breaks while using "vue-cli-service build" due to unsafe-eval

I am developing a chrome extension using vue 3, vue-router and vuex based on Kocal's project which uses vue-cli under the hood. I used whenever possible Single File Components with extensive use of vue bindings.
Everything works perfect on development mode but I recently tried to build the application for production and I encountered this error with partial rendering:
chunk-vendors.f6de00a6.js:11 EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'".
After a few days of digging, my understanding is that either webpack or vue compiling system is messing with CSP by referring/injecting code through eval scripts. As I am fairly new to this, it's hard for me to read to distinguish what I can do.
I tried different approaches:
defining $vue alias to a runtime only build in vue.config.js (supposedly removing unsafe eval by having code compiled before runtime but ending with a new error: Uncaught TypeError: Object(...) is not a function for o=Object(n["withScopeId"])("data-v-21ae70c6");)
using render() function at root
adding "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", to manifest.json
switching a component to render() to see if I have better chance with the partial rendering, but ending up with nothing being displayed although having console.log from render being executed.
Adding a config to chainWebpack splitting manifest and inline manifest on vue.config
What puzzles me is that I can't shake off the unsafe-eval, with at best a partial display, at worst a blank page. Bindings seem to be shaken off regardless and using a router-link to change page will give a blank page.
Edit: After digging through compiled code from webpack and setting minimize opt to false, it seems the error comes from a vendor: vue-i18n
The eval is likely coming from Webpack, due to an issue with global scoping.
see link for more detail https://mathiasbynens.be/notes/globalthis
Could you try adding this configuration to vue.config.js
module.exports = {
configureWebpack: {
node: {
global: false
},
plugins: [
new webpack.DefinePlugin({
global: "window"
})
]
}
};
tl;dr: Check your dependencies/packages, including those you wouldn't think they use unsafe-eval.
After digging into webpack internals and components building for vue3, here are the takeaways:
using Single File Components and default vue-cli config is ok as it will indeed just need vue runtime, so no unsolicited unsafe-eval
webpack config as below works:
module.exports = {
configureWebpack: {
plugins: [
new webpack.DefinePlugin({
global: "window" // Placeholder for global used in any node_modules
})
]
},
...
};
// Note that this plugin definition would break if you are using "unit-mocha" module for vue-cli
In the end, the issue was a dependency I was using for i18n vue-i18n#next, after removing it and switching to chrome's i18n way, it's now working.

Setup Babel + Uglify + Karma using Grunt

I´m trying to setup a build workflow using the aforementioned technologies, but I´m getting the following error, which seems very generic upon running tests on karma:
TypeError: 'undefined' is not an object (evaluating 'a.Sifter=b()')
This happens even without adding any ECMSA6 specific feature. The same workflow works fine without the transpiling phase in the workflow.
What I tried was to set the babeljs after a concatenation phase and before executing a uglifying on it, like the following snippet:
var defaultTasks = [
"sass:prod", // compile scss sources
"cleanAll", // clean folders: preparing for copy
"copyAll", // copying bower files
"cssmin:customVendor", // minify and concat 'customized from vendor' css
"concat:vendorStyles", // concat vendors's css + minified 'customized from vendor' and distribute as 'css/vendor.css'
"uglify:rawVendors", // minifies unminified vendors
"concat:vendorScripts", // concat vendors's scripts and distribute as 'scripts/vendor.js'
"ngAnnotate:app", // ng-annotates app's scripts
"concat:appScripts", // concat app's (customized from vendor's + ng-annotated + customer's)
"babel",// uses babeljs to convert brandnew ES6 javascript into ES5 allowing for old browsers
"uglify:app" // minify app script and distribute as 'scripts/app.js'
];
if (!skipTest) {
defaultTasks.push("karma:target"); // run tests on minified scripts
}
The imporant definitions are shown:
babel: {
options: {
"presets": ['es2015']
},
dist: {
files: {
"<%= concat.appScripts.dest %>": "<%= concat.appScripts.dest %>"
}
}
},
uglify: {
options: {
mangle: {
except: [
"jQuery", "angular", "tableau", "LZString", "moment", "Moment", "Modernizr",
"app", "modules"
]
}
},
app: {
files: [{
src: ["<%= concat.appScripts.dest %>"],
dest: "<%= app.dist %>/scripts/app.js"
}]
}
},
I´ve tested the transpile a bit, running the default logic from babel url, and it works well, converting basic stuff.
Is there any better workflow that I could use to still run the tests against the same code that would be executed for real?
Thanks
In the end, the workflow was correct.
I just need to modify the filesets a bit in order to avoid transpiling the selectize.js file (which wasn´t really needed).
However, not sure why it was breaking
That solved to me, so I´m closing the question, but perhaps might be useful for someone else.

Using Dojo with Tapestry 5.4

I am planning to use Dojo toolkit with Tapestry 5.4. I started off with the tapestry quickstart project and tried to include dojo. However, I have been facing a lot of issues w.r.t the new require mechanisms.
- Unknown Type error - require is not a function
- Unable to load the dojo module
webapp Directory structure
webapp
+------- mybootstrap
+----------- js (part of tapestry quick start project)
+------- js (js folder I added for Dojo)
+----------- dojo (All dojo files here)
Using it with Tapestry 5.3 was pretty simple - including the dojo.js file in the layout component. The same thing does not work in 5.4
I have tried using requirejs data-main attribute, but still stuck with it.
Any help will be appreciated.
Put all your dojo files in webapp\js folder.
your folder structure should be like
// Folder structure
-webapp
-js
-dojo
-digit
-dojox
Note: Make sure you provide the access to js/* path. So that url : http://localhost:8080/app/js/dojo/dojo.js accessible.
Put a script tag inside your tapestry page (*.tml) and add dojo modules using requireJS using below script,
<script type="text/javascript">
setTimeout(
function() {
var dojoConfig = {
async : true
};
require.config({
packages :
[ {
name : 'dojo',
location : '../js/dojo'
} ],
});
require(
[ 'dojo', 'dojo/dom' ],
function(dojo, dom) {
console.log(dojo);
dom.byId("myDiv").innerHTML = "updatedHTML content";
});
}, 1000);
</script>
thats it.