Giter Site home page Giter Site logo

toast's Introduction

Toast v3

Toast is a promise-based JS/CSS loader for the browser. It aims to optimize web site performance by loading your assets asynchronoulsy.

Quick note on IE9/10 support

Support has been dropped for these browsers since Mocha/Sinon (which is used to run our tests) does not support them anymore. Since it would take some time to migrate the tests, that IE9/10 is not supported anymore by Microsoft, and that its market share have dropped under 1%, we took the decision to stop our support too.

For the time being, Toast 3.0.2 will work with IE9/10. Since the code shouldn't evolve too much, you should be safe in the far future until Toast reaches a breaking change.

Compatibility list

Toast is tested against:

  • Chrome 83 (older version should be good too)
  • Firefox 76 (older version should be good too)
  • Edge 83 (older version should be good too)
  • Safari 11-13
  • IE11
  • Android 4.4-10
  • iOS 10-13

Set up

The preferred way to load toast in your application is to install it via NPM (or Yarn), and import it directly in your codebase (it has a very small footprint, and the sooner it's loaded the better).

npm install toast-loader

You have several options to load it in your code depending on your application environment:

  • by inlining it in a <script> tag
  • with const { toast } = require('toast-loader')
  • with import { toast } from 'toast-loader'

You can also load it from the usual <script> tag in your <head>, but I advise you to use a CDN instead of loading it from your own server:

<head>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
</head>

Be sure to use the latest version of Toast and keep a fixed version in production environment (to avoid breaking changes).

The API

toast.css(url: string): Promise
toast.js(url: string): Promise
toast.all(urls: string[]): Promise

Examples

if (dark_mode === true) {
    toast.css('styles/dark.css')
} else {
    toast.css('styles/light.css')
}
const handleErrors = error => {
    console.log(error)
}

toast.js('http://some.cdn.com/jquery.js')
    .then(() => {
        toast.js('http://some.cdn.com/jquery-myplugin.js')
            .then(() => $('.someClass').myPlugin())
            .catch(handleErrors)
        })
    })
    .catch(handleErrors)
await toast.all([
    'assets/css/styles1.css',
    'assets/js/script1.js',
    'assets/js/script2.js',
    'assets/css/styles2.css',
    'assets/js/script3.js',
])
console.log('Everything has been loaded, yay!')

toast.all relies on automatic extension detection. If your URL does not contain a file extension you'll need to use Promise.all instead and do some extra work:

await Promise.all([
    toast.css('assets/css/styles1'),
    toast.js('assets/js/script1'),
    toast.js('assets/js/script2'),
    toast.css('assets/css/styles2'),
    toast.js('assets/js/script3'),
])
console.log('Everything has been loaded, yay!')

Browser compatibility

  • IE10 support (and prior) has been removed since it's not supported by Microsoft anymore and their market share have dropped under 1%
  • Toast is using built-in promises, so if you need to support I11, you must add the promise-polyfill library before loading toast: here's the compatibility table for the Promise feature
  • for your information, IE11 and Edge never trigger error event on CSS loading if something goes wrong; keep this in mind when you're using catch promise block
  • if you want to learn more about SCRIPT/LINK node feature support details, you can take a look at this compatibility table

Development

Install the dependencies with:

npm install

And build the lib with:

npm run build

Look at the scripts in package.json file for more details.

Testing

Tests are written with Mocha and Sinon, and can be run with:

npm run test

It should open your default browser (under a Gnome desktop). If not, just drag and drop the tests/index.html in your preferred browser.


These tests are just for local debugging when in development phase but they need to pass the Karma tests. Karma is a tool to execute unit tests on remote browsers with Selenium/Appium. To be able to run them, you'll need an account on BrowserStack. It's the only service that have a free plan for open-source projects.

When your account is ready, you must prepare your environment by setting global variables in a file that is loaded when your console initializes, like .bashrc, .zshrc or .profile:

  • go to the Automate page
  • display your ACCESS KEY (it's accessible on the right of the search bar)
  • set your env variables like so:
    export BROWSERSTACK_USERNAME="<your_username>"
    export BROWSERSTACK_ACCESS_KEY="<your_access_key>"

Then, run the karma tests with:

npm run karma:all

The results will be displayed in the console and on the Automate page of your account.

If you want to only run tests on a specific browser you can use one of the following commands:

npm run karma:chrome
npm run karma:firefox
npm run karma:safari13
npm run karma:safari12
npm run karma:safari11
npm run karma:edge
npm run karma:ie11
npm run karma:android10
npm run karma:android9
npm run karma:android8
npm run karma:android7
npm run karma:android6
npm run karma:android5
npm run karma:android44
npm run karma:ios13
npm run karma:ios12
npm run karma:ios11
npm run karma:ios10

Note: I don't know why but the tests can be unstable in some VMs when running all Karma tests in parallel; don't hesitate to re-run tests on a specific VM to verify.

License

MIT.

toast's People

Contributors

dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

toast's Issues

`toast.min.js` for bower

Wouldn't it be better to name the minified file without a specific version?
Currently, when installing via bower, it's typically included that way:

<script src="bower_components/toast/toast-1.2.3.min.js"></script>

As a dependency, its version may change some day and break that inclusion. Having the file called toast.min.js would avoid that.

Possibly the version could be prepended as a commentary to the minified source.

load external resource like google webfonts

Hey, just wanted to load a google webfont using toast but it fails
Error
Uncaught TypeError: Cannot read property '1' of null
which refers to this line
b=/(^.+\.\w+)(\?.*)?$/.exec(resource)[1];

Normally I used loadCSS from FilamentGroup but in this project I'm already using toast so why including two resource loaders..
I haven't actually looked into the source in this case and only tested with the webfont so maybe external sources are working in general..

Would love to use toast for loading the font asynchronously ๐Ÿ‘ :D

Cheers

Mock HTTP calls in tests

Currently we're testing live on S3 but calls should happen locally. Hence we should handle assets with a local server in Node/Deno.

Does it load in the specified order?

Hi, from what I see, the scripts creates tags in the <head> sequentially.
This is ok with CSS, bu what about JS? will the browser wait for all the JS to load before interpreting the loaded scripts?

Thank you

Toast not defined issue

Thanks for this nice little helper!
Got a little issue with console saying "Toast not defined"

After changing L134 to return toast; it's working now :)

[enhancement] Add missing bower.json.

Hey, maintainer(s) of pyrsmk/toast!

We at VersionEye are working hard to keep up the quality of the bower's registry.

We just finished our initial analysis of the quality of the Bower.io registry:

7530 - registered packages, 224 of them doesnt exists anymore;

We analysed 7306 existing packages and 1070 of them don't have bower.json on the master branch ( that's where a Bower client pulls a data ).

Sadly, your library pyrsmk/toast is one of them.

Can you spare 15 minutes to help us to make Bower better?

Just add a new file bower.json and change attributes.

{
  "name": "pyrsmk/toast",
  "version": "1.0.0",
  "main": "path/to/main.css",
  "description": "please add it",
  "license": "Eclipse",
  "ignore": [
    ".jshintrc",
    "**/*.txt"
  ],
  "dependencies": {
    "<dependency_name>": "<semantic_version>",
    "<dependency_name>": "<Local_folder>",
    "<dependency_name>": "<package>"
  },
  "devDependencies": {
    "<test-framework-name>": "<version>"
  }
}

Read more about bower.json on the official spefication and nodejs semver library has great examples of proper versioning.

NB! Please validate your bower.json with jsonlint before commiting your updates.

Thank you!

Timo,
twitter: @versioneye
email: [email protected]
VersionEye - no more legacy software!

Add Node loading support as a separate build

It was firstly planned to support node loading in the v3 but the library was twice the size (1.6kb) so it was dropped out.

It would be a great idea to restore this support as a separate build since it can be useful to have a cross-browser support of this.

Here's an example of the API:

<script id="jquery" src="http://some.cdn.com/jquery.js"></script>
await toastNode.js(document.querySelector('#jquery'))
// Do some actions

Find a way to test UMD

To be sure that everything is working in every environment, we should find a way to test the import of toast. We need to support and add examples in the README for:

  • window global
  • ES6 imports
  • Service Worker
  • CommonJS modules
  • AMD modules

Feature: Option to only load script/stylesheet if it is not already in dom

I am wondering if you would consider providing a means to tell toast to load a resource only if it is not already loaded. I'm not sure how this would look in terms of an api. Also would the size increase for toast be acceptable?


The backstory

I'm using toast in a small project -- a bookmarklet actually. The bookmarklet is simply a conduit for injecting the necessary script and stylesheets. I originally wrote a small-ish loader to handling including scripts and styles when the bookmarklet is activated.

I switched to toast when I discovered it a short while ago. It does the job well -- thanks!

While integrating toast into the bookmarklet, I noticed that toast faithfully re-includes the script+style whenever the bookmarklet is clicked. I had a hackish ifNotExists() check in my custom implementation. I have implemented a similar workaround for toast, simplified version below.

var js = "http://www.example.com/crazy.js",
    css = "http://www.example.com/wild.css";

if ( !scriptExists( js ) ) {
    toast( js, css, ready );
} else {
    ready();
}

function ready() {
    // go!
}

function scriptExists( url ) {
    var elements = document.getElementsByTagName('script');

    if ( elements && elements.length > 0 ) {
        for(var i=0, max=elements.length; i<max; i++) {
            if ( elements[i]['src'] == url ) {
                return true;
            }
        }
    }
    return false;
}

I think this would be very helpful for single page apps that load widgets/resources on the fly.

Thanks for reading

JSON

Is it possible to pull down JSON and assign it to a variable with toast?

Be sure that script is loaded

From your wiki, I've read:

Sometimes, on some browsers, scripts are not parsed yet when we want to use them (like calling a function from that script). To resolve that issue, toast provides a simple way:

toast(
    'scripts/jquery.js',
    function(){
        // The callback will be called until `$` is not set
        if(!window.$){
            return false;
        }
        // jQuery actions
        // .....
    }
);

When it could happen, I don't really understand. If loader provide callback function, it means, that callback will be called when loader has already load the script, than functions from this script are available.

So, I need if (!some_var_from_script){ return false;} protection in every script I load/

Missing Timeout Argument?

I don't know if it's just a forgotten argument or what, but Line 34 is just setTimeout(isComplete); with no timeout in miliseconds. Is this correct?
If not, I just read over the MDN doc on setTimeout and it might be helpful to note that 4ms is the minimum but 10 is safer cross-browser.

Edit: Line 43 and 62 are missing it as well.

Inline code feature

Hello,
after a couple of years your project is still very useful. For simple application it has a tiny size and it is a big advantage. It is useful for both, js and css. Updating a project would be appreciated by your users.

It is not covered in your docs but perhaps a useful feature. It is possible to include as parameters an inline code instead of a path to a resource. It can be used for a dependency code that is small enough to be included inline.
For example

toast(
	'[css]https://fonts.googleapis.com/css?family=.....',
	'../css/bootstrap.min.css',
	'../css/styles.min.css',
	'js/jquery-2.0.0.min.js',

	function() {},
	'js/bootstrap.min.js',

	function() {},
	'js/app.min.js',

	function() {},
	'[js]https://www.googletagmanager.com/gtag/js?id=UA-.....',

	function() {
		window.dataLayer = window.dataLayer || [];
		function gtag(){dataLayer.push(arguments);}
		gtag('js', new Date());
		gtag('config', 'UA-.....');
	}
);

Could you please confirm that it is a proper use of toast v2, and there is no any hidden problems. Thanks again for your nice code.

Nice

Nice job!

Michel

Allow loading stylesheets with cache-busting suffixes

The current snippet of code that figures out if you are trying to load a css or javascript resource is very strict.

https://github.com/pyrsmk/toast/blob/master/src/toast.js#L56

Since it expects the resource name to absolutely end in ".css" it is impossible to use other naming conventions e.g. "cache buster" like http://www.example.com/static/styles/some-facy-stuff.css?v=20131201

Kindly consider supporting such formats as they are used quite a bit.

My suggestion is that instead of using the regex \.css$ you could use \.css[^\.]*$. It's an example of a more relaxed regex I saw used in another loader (I forget which one so I can't properly attribute source here).

The test then becomes:

// CSS
if(/\.css[^\.]*$/.test(resource)){
    // Create LINK element
    // ...
} 
// JS
else{
    // Create SCRIPT element
    // ...
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.