-
-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error with auto-traced jQuery and Bootstrap v3 #955
Comments
Following the cookbook, are you sure you have That deps (shim) should enforce the order of jquery and bootstrap. |
Yes, this is the
The test I make to reproduce the issue is adding/removing the
|
There must be some regression in latest beta. But I can not do anything now because of vacation. I will come back to you on this bug. Sorry for the inconvenience. |
@chabou-san could you try It should fix the Bootstrap v3 problem, let me know if it works. Thx! |
1.0.0-beta.5 released, pls test against it. |
Just tested it, and it's not fixed sorry. Am I making myself clear ? |
The sort is based on package name jquery, not module name jquery/dist/jquery. Can you sent me your generated vendor-bundle.js in gitter or discourse? I need to see what’s happening inside. Thx! |
✅ Done on Aurelia-discourse.
Ah, ok. But I can tell that the array Edit: the more I think of it, the more I'm convinced that it comes from the use of a |
Thx for the file vendor-bundle, you can remove the gist now. I can reproduce the issue. Working on it, the sorting is still unstable, because not all combination of two packages were checked by the sorting. |
The bug can be demonstrated by this:
|
@fkleuver can I borrow you for few minutes? How to make the above code stable? |
@huochunpeng sure.. let me understand the sorting rules correctly.. what is the meaning of sorting first by moduleId and then by dependencies? is your intent to fall back to sorting by dependencies if the moduleId is identical, or are both parts always meant to influence the sort? |
Actually, let me ask a different question. At what point / where / when do you decide that module A should come before module B? |
@fkleuver I am talking about the simple a,b,c sorting snippet above. Forget about the cli sorting, cli sorting is to ensure order of shimmed packages. For instance, I want to make sure string "a" is after string "c", and don't care about other strings (don't care about the order between "a" and "b", or "b" and "c", or "x" and "y". |
@chabou-san you can temporarily work around this issue with wrapShim. wrapShim delays executing of bootstrap js to the time you do
|
For it to be stable, you need to include the in-between values in the sort as well (less-than operator). I believe this should work (you don't necessarily have to have the last function compare(a, b) {
if (a === b) return 0;
if (a === 'a' && (b === 'c' || b < 'c')) return 1;
if (b === 'a' && (a === 'c' || a < 'c')) return -1;
return a < b ? -1 : 1;
} |
Thx @fkleuver I will see what I can do. |
Basically you just want to be able to tell any given two modules "you should come after this one and you should come after that one", which you might need to tell to different combinations multiple times right? For dependency order. Or am I wrong |
Might be helpful, here's how rollup approaches this https://github.com/rollup/rollup/blob/841a5366988c945e7cd342b05a8aa8eb9c3411a0/src/utils/execution-order.ts |
I have two choices:
Then sort them separately. |
I don't know enough about the cli internals to be able to decipher the precise implications of what you just described, unfortunately. Could you summarize into a bullet list of abstract sorting rules? e.g. "if a is a shim and b is ... then a comes before b". I'll be able to help you more easily with the sorting then. |
To make a legacy lib into AMD module, we use shim config, so for bootstrap v3, we says The sorting rule is, for shimmed package "foo", if it depends on "bar", ensure package "bar" is before "foo". Pseudo code function sort(packageA, packageB) {
let aName = packageA.name;
let bName = packageB.name;
let aDeps = packageA.shimDeps;
let bDeps = packageB.shimDeps;
// a must be after b
if (aDeps && aDeps.includes(bName)) return 1;
// b must be after a
if (bDeps && bDeps.includes(aName)) return -1;
// don't care
return 0;
} |
How about a regular topological sort then? function sort(packages) {
const sorted = [];
const visited = {};
packages.forEach(function visit(current) {
const { name, deps } = current;
visited[name] = true;
deps.forEach(dep => {
if (!visited[dep]) {
visit(dep);
}
});
if(sorted.indexOf(current) === -1) {
sorted.push(current);
}
});
return sorted;
} var pkg1 = { name: 'pkg1', deps: [] };
var pkg2 = { name: 'pkg2', deps: [] };
var pkg3 = { name: 'pkg3', deps: [] };
var pkg4 = { name: 'pkg4', deps: [] };
var pkg5 = { name: 'pkg5', deps: [] };
pkg2.deps.push(pkg4);
pkg3.deps.push(pkg4);
pkg1.deps.push(pkg3);
pkg2.deps.push(pkg1);
pkg5.deps.push(pkg1);
pkg5.deps.push(pkg2);
pkg5.deps.push(pkg3);
pkg5.deps.push(pkg4);
var packages = [pkg1, pkg2, pkg3, pkg4, pkg5]
packages;
// 0: {name: "pkg1", deps: Array(1)}
// 1: {name: "pkg2", deps: Array(2)}
// 2: {name: "pkg3", deps: Array(1)}
// 3: {name: "pkg4", deps: Array(0)}
// 4: {name: "pkg5", deps: Array(4)}
sort(packages);
packages;
// 3: {name: "pkg4", deps: Array(0)}
// 2: {name: "pkg3", deps: Array(1)}
// 0: {name: "pkg1", deps: Array(1)}
// 1: {name: "pkg2", deps: Array(2)}
// 4: {name: "pkg5", deps: Array(4)} |
Awesome! |
let me know if works / doesnt work :) |
It works, slightly changed to function sort(packages) {
const sorted = [];
const visited = {};
packages.forEach(function visit(current) {
const { name, deps } = current;
if (visited[name]) return; //here
visited[name] = true;
deps.forEach(visit); //here
sorted.push(current); // and here
});
return sorted;
} |
Hi @chabou-san can you try |
Ok, I can confirm it's working for me now. 👍 Many thanks. 😄
Don't worry, I've always had a workaround by setting |
I'm submitting a bug report
1.0.0-beta.3
Please tell us about your environment:
Operating System:
OSX 10.x
Node Version:
8.12.0
NPM Version:
yarn 1.10.1
Browser:
Chrome 70 | Firefox 63.0 | Safari 12.0
Language:
ESNext
Loader/bundler:
RequireJS
Current behavior:
I've just upgraded an old app of mine from Aurelia-cli
v0.33.0
to1.0.0-beta.3
. Due to the major changes, I tried to use the recipes described in the cookbook for bothjQuery
andBootstrap v3
.The recipe for
jQuery
basically says it can be auto-traced (so I removed it from myaurelia.json
).The recipe for
bootstrap v3
says it shall be manually configured inaurelia.json
(so I updated my conf to remove the CSS resource I have previously added, but that was it).When using both recipes, and since
bootstrap
depends onjQuery
, my app is bundled without warning, but when I execute it, I got an error where Bootstrap says it requires jQuery but can't find it, whereas au-cli has the (expected) following trace:When I add the
jQuery
dependency back into myaurelia.json
, everything works as expected.Since
jQuery
is auto-traced, it is probably added (in thevendor-bundle.js
file) AFTER the manually-tracedBootstrap v3
library, even though bootstrap explicitly depends onjQuery
. I guess that whenjQuery
is manually-traced, dependency resolution succeeds in placingjQuery
beforeBootstrap v3
and thus it explains why my app works.What is the expected behavior?
I expect my application not to crash when I follow the recipes. :-)
What is the motivation / use case for changing the behavior?
I want the conjunction of the two recipes to work (but I'm not sure it is even possible without a major rewrite), or at least have the legacy bootstrap's recipe corrected to reflect the incompatibility of the two recipes.
The text was updated successfully, but these errors were encountered: