loadjs icon indicating copy to clipboard operation
loadjs copied to clipboard

Announcement: New version with support for CSS files

Open amorey opened this issue 9 years ago • 12 comments

Hi Everyone,

The newest version of LoadJS (2.1.0) includes support for fetching CSS files:

loadjs(['/path/to/foo.css', '/path/to/bar.js'], {
  success: function() { /* foo.css and bar.js loaded */ },
  fail: function(depsNotFound) { /* foo.css or bar.js didn't load */ }
});

Please try it out and let us know what you think!

Andres

https://github.com/muicss/loadjs https://www.npmjs.com/package/loadjs

amorey avatar Jun 19 '16 16:06 amorey

When I tried to load css file in chrome, I got following error. loadjs.js:104 Uncaught TypeError: Cannot read property 'length' of null

// treat empty stylesheets as failures (to get around lack of onerror
// support in IE
if (e.sheet && !e.sheet.cssRules.length) result = 'e';

without this line, everything is fine.

monad98 avatar Jul 21 '16 23:07 monad98

Interesting, it seems like cssRules can be null under certain conditions. Can you describe how to reproduce the error?

amorey avatar Jul 22 '16 06:07 amorey

It happens when fetching remote css file. For example,

<!doctype html>
<html>
<head>
    <script src="./loadjs.js"></script>
    <script>
        window.addEventListener('load', function(ev) {
            loadjs('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css',
                    function() {
                log('bootstrap loaded');
            });
        });
    </script>
</head>
<body>
<h1>This should be bootstrap style btn-group and it works except error in console.</h1>
<div class="btn-group" role="group">
    <button type="button" class="btn btn-primary">Left</button>
    <button type="button" class="btn btn-danger">Middle</button>
    <button type="button" class="btn btn-success">Right</button>
</div>
</body>
</html>

monad98 avatar Jul 22 '16 18:07 monad98

@monad98 Thanks again for reporting this issue. As you pointed out, the problem is that Chrome sets cssRules to null for external stylesheets. Unfortunately, other browsers raise "Permission denied" errors when accessing cssRules so the solution isn't as simple as checking the attribute first.

The root of the problem is that in IE <link> tags don't support onerror callbacks so instead we have to inspect the CSS to detect load failures. After playing around with a few different options I think the best solution is to isolate IE so that the code block doesn't get executed by other browsers: https://github.com/muicss/loadjs/blob/css-bugfix/src/loadjs.js#L104-L114

Let me know what you think about this solution!

amorey avatar Jul 25 '16 01:07 amorey

It seems a good solution and works fine with Chrome, Safari, Firefox ! 👍 Thank you. When is this new version available as a npm package?

monad98 avatar Jul 25 '16 07:07 monad98

Done! It's available via NPM as v2.1.1: https://www.npmjs.com/package/loadjs

Let me know if you notice any more problems!

amorey avatar Jul 25 '16 08:07 amorey

I was about to ask, if the regular expression to check for CSS files could be changed to something like /.css($|\?)/ or /^css:|\.css$/ (allowing for URLs like css:/generated/style/sheet.php) to match files without proper .css extension.

However I could hack around that problem by adding #.css (a dummy fragment identifier) to the stylesheet URL:

loadjs('/generated/style/sheet.php?foo=bar#.css');

Boldewyn avatar Dec 22 '16 13:12 Boldewyn

I agree - it'd be nice to support css files without a .css suffix. Have you seen the css: prefix used somewhere else? What do you think about using #.cssfor now until we can settle on a more general solution?

amorey avatar Dec 24 '16 08:12 amorey

A similar project, Toast, uses a [css] prefix. The Webpack CSS loader uses the syntax css-loader!./file.css.

Personally, I thought, that css: looks more "URL like" (like the view-source: pseudo-protocol of Firefox).

For now I'm fine with the #.css hack, since basically all browsers strip it from the requested URL anyway, so it's only visible in the href of the generated <link> if anyone's looking. (Scripts sometimes use the hash in their calling <script>'s src for configuration, but that's nothing to worry for CSS.)

Boldewyn avatar Dec 25 '16 19:12 Boldewyn

Ok, let's keep the #.css hack for now and give others a chance to weigh in.

amorey avatar Dec 27 '16 20:12 amorey

@Boldewyn The latest version of LoadJS (v3.5.0) has support for "css!" prefix to force treating files as stylesheets: https://github.com/muicss/loadjs https://www.npmjs.com/package/loadjs

amorey avatar Mar 28 '17 11:03 amorey

Thank you! I'll go trying it immediately.

Boldewyn avatar Mar 28 '17 11:03 Boldewyn