jquery/build/fixtures/README.md

184 lines
6.3 KiB
Markdown
Raw Normal View History

# jQuery
> jQuery is a fast, small, and feature-rich JavaScript library.
For information on how to get started and how to use jQuery, please see [jQuery's documentation](https://api.jquery.com/).
For source files and issues, please visit the [jQuery repo](https://github.com/jquery/jquery).
If upgrading, please see the [blog post for @VERSION](@BLOG_POST_LINK). This includes notable differences from the previous version and a more readable changelog.
## Including jQuery
Below are some of the most common ways to include jQuery.
### Browser
#### Script tag
```html
<script src="https://code.jquery.com/jquery-@VERSION.min.js"></script>
```
or, to use the jQuery ECMAScript module:
```html
<script type="module">
import { $ } from "https://code.jquery.com/jquery-@VERSION.module.min.js";
</script>
```
or:
```html
<script type="module">
import { jQuery } from "https://code.jquery.com/jquery-@VERSION.module.min.js";
</script>
```
All jQuery modules export named `$` & `jQuery` tokens; the further examples will just show `$`. The default import also works:
```html
<script type="module">
import $ from "https://code.jquery.com/jquery-@VERSION.module.min.js";
</script>
```
However, named imports provide better interoperability across tooling and are therefore recommended.
Sometimes you dont need AJAX, or you prefer to use one of the many standalone libraries that focus on AJAX requests. And often it is simpler to use a combination of CSS, class manipulation or the Web Animations API. Similarly, many projects opt into relying on native browser promises instead of jQuery Deferreds. Along with the regular version of jQuery that includes the `ajax`, `callbacks`, `deferred`, `effects` & `queue` modules, weve released a “slim” version that excludes these modules. You can load it as a regular script:
```html
<script src="https://code.jquery.com/jquery-@VERSION.slim.min.js"></script>
```
or as a module:
```html
<script type="module">
import { $ } from "https://code.jquery.com/jquery-@VERSION.module.slim.min.js";
</script>
```
#### Import maps
To avoid repeating long import paths that change on each jQuery release, you can use import maps - they are now supported in every modern browser. Put the following script tag before any `<script type="module">`:
```html
<script type="importmap">
{
"imports": {
"jquery": "https://code.jquery.com/jquery-@VERSION.module.min.js",
"jquery/slim": "https://code.jquery.com/jquery-@VERSION.module.slim.min.js"
}
}
</script>
```
Now, the following will work to get the full version:
```html
<script type="module">
import { $ } from "jquery";
// Use $ here
</script>
```
and the following to get the slim one:
```html
<script type="module">
import { $ } from "jquery/slim";
// Use $ here
</script>
```
The advantage of these specific mappings is they match the ones embedded in the jQuery npm package, providing better interoperability between the environments.
You can also use jQuery from npm even in the browser setup. Read along for more details.
### Using jQuery from npm
There are several ways to use jQuery from npm. One is to use a build tool like [Webpack](https://webpack.js.org/), [Browserify](https://browserify.org/) or [Babel](https://babeljs.io/). For more information on using these tools, please refer to the corresponding project's documentation.
Another way is to use jQuery directly in Node.js. See the [Node.js pre-requisites](#nodejs-pre-requisites) section for more details on the Node.js-specific part of this.
To install the jQuery npm package, invoke:
```sh
npm install jquery
```
In the script, including jQuery will usually look like this:
```js
import { $ } from "jquery";
```
If you need to use jQuery in a file that's not an ECMAScript module, you can use the CommonJS syntax:
```js
const $ = require( "jquery" );
```
Core: Fix the exports setup to make bundlers work with ESM & CommonJS We cannot pass a single file via the `module` condition as then `require( "jquery" )` will not return jQuery but instead the module object with `default`, `$` & `jQuery` as keys. Instead: 1. For Node.js, detected via the `node` condition: 1. Expose a regular CommonJS version to `require` 2. Expose a tiny wrapper over CommonJS to `import` 2. For bundlers, detected via the `module` condition: 1. Expose a regular ESM version to `import` 2. Expose a tiny wrapper over ESM to `require` 3. If neither Node.js nor bundlers are detected (no `node` or `module` conditions`): 1. Expose a regular CommonJS version to `require` 2. Expose a regular ESM version to `import` The reasons for such definitions are as follows: 1. In Node.js, one can synchronously import from a CommonJS file inside of an ESM one but not vice-versa. To use an ESM file in a CommonJS one, a dynamic import is required and that forces asynchronicity. 2. In some bundlers CommonJS is not necessarily enabled - e.g. in Rollup without the CommonJS plugin. Therefore, the ESM version needs to be pure ESM. However, bundlers allow synchronously calling `require` on an ESM file. This is possible since bundlers merge the files before they are passed to the browser to execute and the final bundles no longer contain async import code. 3. Bare ESM & CommonJS versions are provided to non-Node non-bundler environments where we cannot assume interoperability between ESM & CommonJS is supported. 4. Bare versions cannot be supplied to Node or bundlers as projects using both ESM & CommonJS to fetch jQuery would result in duplicate jQuery instances, leading to increased JS size and disjoint data storage. In addition to the above changes, the `script` condition has been dropped. Only Webpack documents this condition and it's not clear when exactly it's triggered. Adding support for a new condition can be added later without a breaking change; removing is not so easy. The `production` & `development` conditions have been removed as well. They were not really applied correctly; we'd need to provide both of them to each current leaf which would double the size of the definition for the `.` & `./slim` entry points. In jQuery, the only difference between development & production builds is minification; there are no logic changes so we can pass unminified versions to all the tooling, expecting minification down the line. As for the factory entry points: 1. Node.js always gets the CommonJS version 2. Bundlers always get the ESM version 3. Other tools take the ESM version when using `import` and the CommonJS when using `require`. The complexity is lower than for the `.` & `./slim` entry points because there's no default export to handle so Node/bundler wrapper files are not necessary. Other changes: * Tests: Change "node:assert" to "node:assert/strict"; the former is deprecated * Docs: Mention that the CommonJS module doesn't expose named exports * Tests: Run Node & bundler tests for all the above cases Fixes gh-5416 Closes gh-5429
2024-03-11 23:39:34 +00:00
The CommonJS module _does not_ expose named `$` & `jQuery` exports.
#### Individual modules
jQuery is authored in ECMAScript modules; it's also possible to use them directly. They are contained in the `src/` folder; inspect the package contents to see what's there. Full file names are required, including the `.js` extension.
Be aware that this is an advanced & low-level interface, and we don't consider it stable, even between minor or patch releases - this is especially the case for modules in subdirectories or `src/`. If you rely on it, verify your setup before updating jQuery.
All top-level modules, i.e. files directly in the `src/` directory export jQuery. Importing multiple modules will all attach to the same jQuery instance.
Remember that some modules have other dependencies (e.g. the `event` module depends on the `selector` one) so in some cases you may get more than you expect.
Example usage:
```js
import { $ } from "jquery/src/css.js"; // adds the `.css()` method
import "jquery/src/event.js"; // adds the `.on()` method; pulls "selector" as a dependency
$( ".toggle" ).on( "click", function() {
$( this ).css( "color", "red" );
} );
```
### AMD (Asynchronous Module Definition)
AMD is a module format built for the browser. For more information, we recommend [require.js' documentation](https://requirejs.org/docs/whyamd.html).
```js
define( [ "jquery" ], function( $ ) {
} );
```
Node.js doesn't understand AMD natively so this method is mostly used in a browser setup.
### Node.js pre-requisites
Core: Move the factory to separate exports Since versions 1.11.0/2.1.0, jQuery has used a module wrapper with one strange addition - in CommonJS environments, if a global `window` with a `document` was not present, jQuery exported a factory accepting a `window` implementation and returning jQuery. This approach created a number of problems: 1. Properly typing jQuery would be a nightmare as the exported value depends on the environment. In practice, typing definitions ignored the factory case. 2. Since we now use named exports for the jQuery module version, it felt weird to have `jQuery` and `$` pointing to the factory instead of real jQuery. Instead, for jQuery 4.0 we leverage the just added `exports` field in `package.json` to expose completely separate factory entry points: one for the full build, one for the slim one. Exports definitions for `./factory` & `./factory-slim` are simpler than for `.` and `./slim` - this is because it's a new entry point, we only expose a named export and so there's no issue with just pointing Node.js to the CommonJS version (we cannot use the module version for `import` from Node.js to avoid double package hazard). The factory entry points are also not meant for the Web browser which always has a proper `window` - and they'd be unfit for an inclusion in a regular script tag anyway. Because of that, we also don't generate minified versions of these entry points. The factory files are not pushed to the CDN since they are mostly aimed at Node.js. Closes gh-5293
2023-09-19 16:58:24 +00:00
For jQuery to work in Node, a `window` with a `document` is required. Since no such window exists natively in Node, one can be mocked by tools such as [jsdom](https://github.com/jsdom/jsdom). This can be useful for testing purposes.
Core: Move the factory to separate exports Since versions 1.11.0/2.1.0, jQuery has used a module wrapper with one strange addition - in CommonJS environments, if a global `window` with a `document` was not present, jQuery exported a factory accepting a `window` implementation and returning jQuery. This approach created a number of problems: 1. Properly typing jQuery would be a nightmare as the exported value depends on the environment. In practice, typing definitions ignored the factory case. 2. Since we now use named exports for the jQuery module version, it felt weird to have `jQuery` and `$` pointing to the factory instead of real jQuery. Instead, for jQuery 4.0 we leverage the just added `exports` field in `package.json` to expose completely separate factory entry points: one for the full build, one for the slim one. Exports definitions for `./factory` & `./factory-slim` are simpler than for `.` and `./slim` - this is because it's a new entry point, we only expose a named export and so there's no issue with just pointing Node.js to the CommonJS version (we cannot use the module version for `import` from Node.js to avoid double package hazard). The factory entry points are also not meant for the Web browser which always has a proper `window` - and they'd be unfit for an inclusion in a regular script tag anyway. Because of that, we also don't generate minified versions of these entry points. The factory files are not pushed to the CDN since they are mostly aimed at Node.js. Closes gh-5293
2023-09-19 16:58:24 +00:00
For Node-based environments that don't have a global `window`, jQuery exposes a dedicated `jquery/factory` entry point.
To `import` jQuery using this factory, use the following:
```js
import { JSDOM } from "jsdom";
const { window } = new JSDOM( "" );
Core: Move the factory to separate exports Since versions 1.11.0/2.1.0, jQuery has used a module wrapper with one strange addition - in CommonJS environments, if a global `window` with a `document` was not present, jQuery exported a factory accepting a `window` implementation and returning jQuery. This approach created a number of problems: 1. Properly typing jQuery would be a nightmare as the exported value depends on the environment. In practice, typing definitions ignored the factory case. 2. Since we now use named exports for the jQuery module version, it felt weird to have `jQuery` and `$` pointing to the factory instead of real jQuery. Instead, for jQuery 4.0 we leverage the just added `exports` field in `package.json` to expose completely separate factory entry points: one for the full build, one for the slim one. Exports definitions for `./factory` & `./factory-slim` are simpler than for `.` and `./slim` - this is because it's a new entry point, we only expose a named export and so there's no issue with just pointing Node.js to the CommonJS version (we cannot use the module version for `import` from Node.js to avoid double package hazard). The factory entry points are also not meant for the Web browser which always has a proper `window` - and they'd be unfit for an inclusion in a regular script tag anyway. Because of that, we also don't generate minified versions of these entry points. The factory files are not pushed to the CDN since they are mostly aimed at Node.js. Closes gh-5293
2023-09-19 16:58:24 +00:00
import { jQueryFactory } from "jquery/factory";
const $ = jQueryFactory( window );
```
or, if you use `require`:
```js
const { JSDOM } = require( "jsdom" );
const { window } = new JSDOM( "" );
Core: Move the factory to separate exports Since versions 1.11.0/2.1.0, jQuery has used a module wrapper with one strange addition - in CommonJS environments, if a global `window` with a `document` was not present, jQuery exported a factory accepting a `window` implementation and returning jQuery. This approach created a number of problems: 1. Properly typing jQuery would be a nightmare as the exported value depends on the environment. In practice, typing definitions ignored the factory case. 2. Since we now use named exports for the jQuery module version, it felt weird to have `jQuery` and `$` pointing to the factory instead of real jQuery. Instead, for jQuery 4.0 we leverage the just added `exports` field in `package.json` to expose completely separate factory entry points: one for the full build, one for the slim one. Exports definitions for `./factory` & `./factory-slim` are simpler than for `.` and `./slim` - this is because it's a new entry point, we only expose a named export and so there's no issue with just pointing Node.js to the CommonJS version (we cannot use the module version for `import` from Node.js to avoid double package hazard). The factory entry points are also not meant for the Web browser which always has a proper `window` - and they'd be unfit for an inclusion in a regular script tag anyway. Because of that, we also don't generate minified versions of these entry points. The factory files are not pushed to the CDN since they are mostly aimed at Node.js. Closes gh-5293
2023-09-19 16:58:24 +00:00
const { jQueryFactory } = require( "jquery/factory" );
const $ = jQueryFactory( window );
```
#### Slim build in Node.js
Core: Move the factory to separate exports Since versions 1.11.0/2.1.0, jQuery has used a module wrapper with one strange addition - in CommonJS environments, if a global `window` with a `document` was not present, jQuery exported a factory accepting a `window` implementation and returning jQuery. This approach created a number of problems: 1. Properly typing jQuery would be a nightmare as the exported value depends on the environment. In practice, typing definitions ignored the factory case. 2. Since we now use named exports for the jQuery module version, it felt weird to have `jQuery` and `$` pointing to the factory instead of real jQuery. Instead, for jQuery 4.0 we leverage the just added `exports` field in `package.json` to expose completely separate factory entry points: one for the full build, one for the slim one. Exports definitions for `./factory` & `./factory-slim` are simpler than for `.` and `./slim` - this is because it's a new entry point, we only expose a named export and so there's no issue with just pointing Node.js to the CommonJS version (we cannot use the module version for `import` from Node.js to avoid double package hazard). The factory entry points are also not meant for the Web browser which always has a proper `window` - and they'd be unfit for an inclusion in a regular script tag anyway. Because of that, we also don't generate minified versions of these entry points. The factory files are not pushed to the CDN since they are mostly aimed at Node.js. Closes gh-5293
2023-09-19 16:58:24 +00:00
To use the slim build of jQuery in Node.js, use `"jquery/slim"` instead of `"jquery"` in both `require` or `import` calls above. To use the slim build in Node.js with factory mode, use `jquery/factory-slim` instead of `jquery/factory`.