Closed larslaade closed 6 years ago
hi lars :) we are working on an integration of webpack2 into the nikita generator. Thats work in progress but we already found a solution.
strategy is to ignore jsbs in webpack and include all jsbs by hand.
with import-glob its only a single import statement.
we suffix all jsbs with .jsb.js
to avoid interferences with other modules.
our grunt config looks like that:
webpack: (function(){
var webpack = require('webpack');
var plugins = [
new webpack.IgnorePlugin(/^(.*)$/, /node-jsb$/)
];
return {
options: {
entry: {
main: './<%%= paths.src %>/js/_main.js'
},
module: {
exprContextCritical: false,
rules: [
{
test: /\.js$/,
enforce: 'pre',
loader: 'import-glob',
exclude: /node_modules/
},
...
]
},
resolve: {
modules: ['<%%= paths.src %>/js', 'node_modules']
}
},
dev: {
...
plugins: plugins
},
dist: {
...
plugins: plugins
}
};
})()
entry file _main.js looks like this:
import app from './app';
import jsbs from './**/*.jsb.js';
Hi Benny :)
thank you for your fast response. Using the IgnorePlugin my build is working for now. (But the warning is still there.)
It's important to have jsb.registerHandler in your jsb's, because otherwise it cannot map it properly :(.
(But the warning is still there.)
exprContextCritical: false,
does the trick ;)
Is here any update? Having the same problem. And i don't want to use: exprContextCritical: false
first of all: this is not a bug of jsb (see comments above for a working integration with webpack).
exprContextCritical: false
just hide the warnings in this approach.
which problems do you have in detail?
my app.js:
(Same thing when i add via yarn add node-jsb
)
import jsb from '../js/jsb.js'
global.jsb = jsb;
//Some JSB's
the warning:
www-data@40ac6cc5e7be:~$ yarn build
yarn run v1.5.1
$ encore production
Running webpack ...
WARNING Compiled with 1 warnings 10:31:15
warning in ./assets/js/jsb.js
297:20-306:22 Critical dependency: the request of a dependency is an expression
Done in 6.35s.
developer console output:
app.b8ad9cc4.js:24 Uncaught ReferenceError: jsb is not defined
at Object.<anonymous> (app.b8ad9cc4.js:24)
at Object.91bm (app.b8ad9cc4.js:24)
at e (app.b8ad9cc4.js:1)
at Object.<anonymous> (app.b8ad9cc4.js:24)
at Object.ET/6 (app.b8ad9cc4.js:24)
at e (app.b8ad9cc4.js:1)
at 0418 (app.b8ad9cc4.js:1)
at app.b8ad9cc4.js:1
app.b8ad9cc4.js:1 Error: Cannot find module "."
at app.b8ad9cc4.js:24
at app.b8ad9cc4.js:24
e.oe @ app.b8ad9cc4.js:1
Promise.catch (async)
callHandler @ app.b8ad9cc4.js:24
applyBehaviour @ app.b8ad9cc4.js:24
(anonymous) @ app.b8ad9cc4.js:24
app.b8ad9cc4.js:24 Uncaught (in promise) Error: Cannot find module "."
at app.b8ad9cc4.js:24
at app.b8ad9cc4.js:24
do you modified your webpack config like in the comment above?
yea i did, but this cant be the solution. This flag just disable the warning messages. And the error in developer console still there
I figuered out that: require
is part of webpack and jsb library doesn't use require
as webpack wants you to use it.
jsb expects require to behave like require behaves in case of AMD. webpack does not load dynamic versions of modules. So we could create a jsb version, which cannot lazyload requirejs modules.
So basically it's webpacks fault: webpack does not need this feature, neither webpack can use it. Thus it would be great, if webpack wouldn't complain about sourcecode, which it cannot execute ;). Can you fix this by embedding jsb properly with webpack?
webpack does not load dynamic versions of modules
What do you mean with that?
You could use require
and import
in webpack to dynamically load modules even asynchronously.
see https://webpack.js.org/guides/code-splitting/#dynamic-imports
sourcecode, which it cannot execute
Webpack looks for require
and import
statements to load dependencies and build the dependency tree. So the code does not get executed but webpack tries to look ahead and load the entire dependency tree.
See e.g. https://www.bennadel.com/blog/2402-lazy-loading-requirejs-modules-when-they-are-first-requested.htm.
Implementing it like webpack handles it, would mean that the requirejs lazyloading is not possible anymore. We could try to use https://webpack.js.org/api/module-methods/#require-ensure if it's available. But webpacks error message appears, because webpack tries to guess what the code does. But the jsb source doesn't do, what webpack expects it to do ;).
Okay i solved it like:
custom-jsb.js
const handlers = {};
const eventHandlers = {};
const loadJsbHandler = function (element) {
let handler = null;
for (let i = 0; i < element.classList.length; i++) {
if (element.classList[i].startsWith('jsb_') && element.classList[i].length > 4) {
handler = element.classList[i].substr(4);
break;
}
}
const options = JSON.parse(element.dataset.jsb || '{}');
if (handlers[handler]) {
handlers[handler](element, options)
}
};
const jsb = {
on(key, callback) {
eventHandlers[key] = eventHandlers[key] || []
eventHandlers[key].push(callback)
},
off(key, callback) {
if (eventHandlers[key]) {
const index = eventHandlers[key].indexOf(callback)
eventHandlers[key].splice(index, 1);
}
},
whenFired(key, callback) {
// TODO: implement me
},
fireEvent(key, payload) {
(eventHandlers[key] || []).forEach(callback => callback(payload));
},
registerHandler(key, callback) {
handlers[key] = callback;
},
load() {
document.querySelectorAll('.jsb_').forEach(loadJsbHandler);
}
};
document.addEventListener('DOMContentLoaded', function () {
jsb.load()
});
export default jsb;
app.js
import jsb from '../js/custom-jsb';
window.jsb = jsb;
require('../js/LoadOverlay.js')
//...
LoadOverlay.js
LoadOverlay = function (domElement, options) {
// do something
};
jsb.registerHandler('LoadOverlay', LoadOverlay);
Using
<div class="jsb_ jsb_LoadOverlay"></div>
I just didn't know how whenFired
is working... maybe some queueing stuff.
Anyway thanks for quick answer! :)
Please don’t reimplement jsb entirely. /cc @oskarstark
Fixed with jsb 3.1.0
WARNING in ../~/node-jsb/jsb.js 296:20-305:22 Critical dependency: the request of a dependency is an expression
On line number 296 is the require call:
Any hints or suggestions?