3 module.exports = function( grunt ) {
4 function readOptionalJSON( filepath ) {
5 const stripJSONComments = require( "strip-json-comments" );
8 data = JSON.parse( stripJSONComments(
9 fs.readFileSync( filepath, { encoding: "utf8" } )
15 const fs = require( "fs" );
16 const gzip = require( "gzip-js" );
17 const nodeV14OrNewer = !/^v1[0-3]\./.test( process.version );
18 const nodeV17OrNewer = !/^v1[0-6]\./.test( process.version );
19 const customBrowsers = process.env.BROWSERS && process.env.BROWSERS.split( "," );
21 // Support: Node.js <14
22 // Skip running tasks that dropped support for Node.js 10 or 12
23 // in this Node version.
24 function runIfNewNode( task ) {
25 return nodeV14OrNewer ? task : "print_old_node_message:" + task;
28 if ( nodeV14OrNewer ) {
29 const playwright = require( "playwright-webkit" );
30 process.env.WEBKIT_HEADLESS_BIN = playwright.webkit.executablePath();
33 if ( !grunt.option( "filename" ) ) {
34 grunt.option( "filename", "jquery.js" );
38 pkg: grunt.file.readJSON( "package.json" ),
39 dst: readOptionalJSON( "dist/.destination.json" ),
41 files: [ "dist/jquery.js", "dist/jquery.min.js" ],
44 gz: function( contents ) {
45 return gzip.zip( contents, {} ).length;
48 cache: "build/.sizecache.json"
55 plugins: [ "@babel/transform-for-of" ]
59 "test/data/core/jquery-iterability-transpiled.js":
60 "test/data/core/jquery-iterability-transpiled-es6.js"
66 dest: "dist/jquery.js",
71 // Exclude specified modules if the module matching the key is removed
73 ajax: [ "manipulation/_evalUrl", "deprecated/ajax-event-alias" ],
74 callbacks: [ "deferred" ],
75 css: [ "effects", "dimensions", "offset" ],
76 "css/showHide": [ "effects" ],
78 remove: [ "ajax", "effects", "queue", "core/ready" ],
79 include: [ "core/ready-no-deferred" ]
81 event: [ "deprecated/ajax-event-alias", "deprecated/event" ],
82 selector: [ "css/hiddenVisibleSelectors", "effects/animatedSelector" ]
89 destPrefix: "external"
92 "core-js-bundle/core-js-bundle.js": "core-js-bundle/minified.js",
93 "core-js-bundle/LICENSE": "core-js-bundle/LICENSE",
95 "npo/npo.js": "native-promise-only/lib/npo.src.js",
97 "qunit/qunit.js": "qunit/qunit/qunit.js",
98 "qunit/qunit.css": "qunit/qunit/qunit.css",
99 "qunit/LICENSE.txt": "qunit/LICENSE.txt",
101 "requirejs/require.js": "requirejs/require.js",
103 "sinon/sinon.js": "sinon/pkg/sinon.js",
104 "sinon/LICENSE.txt": "sinon/LICENSE"
110 src: [ "package.json" ]
118 // We have to explicitly declare "src" property otherwise "newer"
119 // task wouldn't work properly :/
121 src: [ "dist/jquery.js", "dist/jquery.min.js" ]
130 // Ignore files from .eslintignore
131 // See https://github.com/sindresorhus/grunt-eslint/issues/119
133 .readFileSync( `${ __dirname }/.eslintignore`, "utf-8" )
135 .filter( filePath => filePath )
136 .map( filePath => filePath[ 0 ] === "!" ?
137 filePath.slice( 1 ) :
146 // A special module with basic tests, meant for not fully
147 // supported environments like jsdom. We run it everywhere,
148 // though, to make sure tests are not broken.
175 customContextFile: "test/karma.context.html",
176 customDebugFile: "test/karma.debug.html",
178 ChromeHeadlessNoSandbox: {
179 base: "ChromeHeadless",
180 flags: [ "--no-sandbox" ]
183 frameworks: [ "qunit" ],
184 middleware: [ "mockserver" ],
188 "middleware:mockserver": [
190 require( "./test/middleware-mockserver.js" )
197 // We're running `QUnit.start()` ourselves via `loadTests()`
203 "test/data/jquery-1.9.1.js",
204 "external/sinon/sinon.js",
205 "external/npo/npo.js",
206 "external/requirejs/require.js",
207 "test/data/testinit.js",
212 pattern: "dist/jquery.*",
230 { pattern: "external/**", included: false, served: true },
232 pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
238 reporters: [ "dots" ],
241 // 2 minutes; has to be longer than QUnit.config.testTimeout
242 browserNoActivityTimeout: 120e3,
245 captureTimeout: 20 * 1000,
249 browsers: customBrowsers ||
250 [ "ChromeHeadless", "FirefoxHeadless", "WebkitHeadless" ]
253 browsers: customBrowsers || [ "ChromeHeadless" ],
258 // We're running `QUnit.start()` ourselves via `loadTests()`
268 browsers: customBrowsers || [ "ChromeHeadless" ],
273 // We're running `QUnit.start()` ourselves via `loadTests()`
286 "test/data/jquery-1.9.1.js",
287 "test/data/testinit-jsdom.js",
289 // We don't support various loading methods like esmodules,
290 // choosing a version etc. for jsdom.
293 // A partial replacement for testinit.js#loadTests()
294 "test/data/testrunner.js",
296 // jsdom only runs basic tests
297 "test/unit/basic.js",
300 pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
306 browsers: [ "jsdom" ]
309 // To debug tests with Karma:
310 // 1. Run 'grunt karma:chrome-debug' or 'grunt karma:firefox-debug'
311 // (any karma subtask that has singleRun=false)
312 // 2. Press "Debug" in the opened browser window to start
313 // the tests. Unlike the other karma tasks, the debug task will
314 // keep the browser window open.
316 browsers: [ "Chrome" ],
320 browsers: [ "Firefox" ],
329 files: [ "<%= eslint.dev.src %>" ],
335 "dist/<%= grunt.option('filename').replace('.js', '.min.js') %>":
336 "dist/<%= grunt.option('filename') %>"
339 preserveComments: false,
342 "dist/<%= grunt.option('filename').replace('.js', '.min.map') %>",
347 banner: "/*! jQuery v<%= pkg.version %> | " +
348 "(c) OpenJS Foundation and other contributors | jquery.org/license */",
358 // Load grunt tasks from NPM packages
359 require( "load-grunt-tasks" )( grunt, {
360 pattern: nodeV14OrNewer ? [ "grunt-*" ] : [ "grunt-*", "!grunt-eslint" ]
363 // Integrate jQuery specific tasks
364 grunt.loadTasks( "build/tasks" );
366 grunt.registerTask( "print_old_node_message", ( ...args ) => {
367 var task = args.join( ":" );
368 grunt.log.writeln( "Old Node.js detected, running the task \"" + task + "\" skipped..." );
371 grunt.registerTask( "print_jsdom_message", () => {
372 grunt.log.writeln( "Node.js 17 or newer detected, skipping jsdom tests..." );
375 grunt.registerTask( "lint", [
378 // Running the full eslint task without breaking it down to targets
379 // would run the dist target first which would point to errors in the built
380 // file, making it harder to fix them. We want to check the built file only
381 // if we already know the source files pass the linter.
382 runIfNewNode( "eslint:dev" ),
383 runIfNewNode( "eslint:dist" )
386 grunt.registerTask( "lint:newer", [
389 // Don't replace it with just the task; see the above comment.
390 runIfNewNode( "newer:eslint:dev" ),
391 runIfNewNode( "newer:eslint:dist" )
394 grunt.registerTask( "test:fast", runIfNewNode( "node_smoke_tests" ) );
395 grunt.registerTask( "test:slow", [
396 runIfNewNode( "promises_aplus_tests" ),
398 // Support: Node.js 17+
399 // jsdom fails to connect to the Karma server in Node 17+.
400 // Until we figure out a fix, skip jsdom tests there.
401 nodeV17OrNewer ? "print_jsdom_message" : runIfNewNode( "karma:jsdom" )
404 grunt.registerTask( "test:prepare", [
410 grunt.registerTask( "test", [
416 grunt.registerTask( "dev", [
418 runIfNewNode( "newer:eslint:dev" ),
420 "remove_map_comment",
426 grunt.registerTask( "default", [
427 runIfNewNode( "eslint:dev" ),
431 "remove_map_comment",
434 runIfNewNode( "eslint:dist" ),