diff --git a/package-lock.json b/package-lock.json index 87af6af9dd1c2..cae57f5937eca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "core-js-url-browser": "3.6.4", "csslint": "1.0.5", "element-closest": "3.0.2", + "espree": "9.6.1", "esprima": "4.0.1", "formdata-polyfill": "4.0.10", "hoverintent": "2.2.1", @@ -44,6 +45,7 @@ "@lodder/grunt-postcss": "^3.1.1", "@playwright/test": "1.56.1", "@pmmmwh/react-refresh-webpack-plugin": "0.6.1", + "@types/codemirror": "5.60.17", "@wordpress/e2e-test-utils-playwright": "1.33.2", "@wordpress/prettier-config": "4.33.1", "@wordpress/scripts": "30.26.2", @@ -5131,6 +5133,16 @@ "@types/node": "*" } }, + "node_modules/@types/codemirror": { + "version": "5.60.17", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.17.tgz", + "integrity": "sha512-AZq2FIsUHVMlp7VSe2hTfl5w4pcUkoFkM3zVsRKsn1ca8CXRDYvnin04+HP2REkwsxemuHqvDofdlhUWNpbwfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/tern": "*" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -5420,6 +5432,16 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/tern": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", + "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.3.tgz", @@ -7445,7 +7467,6 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -7468,7 +7489,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -13285,7 +13305,6 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -13302,7 +13321,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" diff --git a/package.json b/package.json index 9ff5ddd3dae97..4bf5b24887cef 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@lodder/grunt-postcss": "^3.1.1", "@playwright/test": "1.56.1", "@pmmmwh/react-refresh-webpack-plugin": "0.6.1", + "@types/codemirror": "5.60.17", "@wordpress/e2e-test-utils-playwright": "1.33.2", "@wordpress/prettier-config": "4.33.1", "@wordpress/scripts": "30.26.2", @@ -79,6 +80,7 @@ "core-js-url-browser": "3.6.4", "csslint": "1.0.5", "element-closest": "3.0.2", + "espree": "9.6.1", "esprima": "4.0.1", "formdata-polyfill": "4.0.10", "hoverintent": "2.2.1", diff --git a/src/js/_enqueues/vendor/codemirror/javascript-lint.js b/src/js/_enqueues/vendor/codemirror/javascript-lint.js new file mode 100644 index 0000000000000..3f98ad523346c --- /dev/null +++ b/src/js/_enqueues/vendor/codemirror/javascript-lint.js @@ -0,0 +1,121 @@ +/** + * CodeMirror JavaScript linter. + * + * @since 7.0.0 + */ + +import CodeMirror from 'codemirror'; + +/** + * CodeMirror Lint Error. + * + * @see https://codemirror.net/5/doc/manual.html#addon_lint + * + * @typedef {Object} CodeMirrorLintError + * @property {string} message - Error message. + * @property {'error'} severity - Severity. + * @property {CodeMirror.Position} from - From position. + * @property {CodeMirror.Position} to - To position. + */ + +/** + * JSHint options supported by Espree. + * + * @see https://jshint.com/docs/options/ + * @see https://www.npmjs.com/package/espree#options + * + * @typedef {Object} SupportedJSHintOptions + * @property {number} [esversion] - "This option is used to specify the ECMAScript version to which the code must adhere." + * @property {boolean} [es5] - "This option enables syntax first defined in the ECMAScript 5.1 specification. This includes allowing reserved keywords as object properties." + * @property {boolean} [es3] - "This option tells JSHint that your code needs to adhere to ECMAScript 3 specification. Use this option if you need your program to be executable in older browsers—such as Internet Explorer 6/7/8/9—and other legacy JavaScript environments." + * @property {boolean} [module] - "This option informs JSHint that the input code describes an ECMAScript 6 module. All module code is interpreted as strict mode code." + * @property {'implied'} [strict] - "This option requires the code to run in ECMAScript 5's strict mode." + */ + +/** + * Validates JavaScript. + * + * @since 7.0.0 + * + * @param {string} text - Source. + * @param {SupportedJSHintOptions} options - Linting options. + * @returns {Promise} + */ +async function validator( text, options ) { + const errors = /** @type {CodeMirrorLintError[]} */ []; + try { + const espree = await import( /* webpackIgnore: true */ 'espree' ); + espree.parse( text, { + ...getEspreeOptions( options ), + loc: true, + } ); + } catch ( error ) { + if ( + // This is an `EnhancedSyntaxError` in Espree: . + error instanceof SyntaxError && + typeof error.lineNumber === 'number' && + typeof error.column === 'number' + ) { + const line = error.lineNumber - 1; + errors.push( { + message: error.message, + severity: 'error', + from: CodeMirror.Pos( line, error.column - 1 ), + to: CodeMirror.Pos( line, error.column ), + } ); + } else { + console.warn( '[CodeMirror] Unable to lint JavaScript:', error ); // jshint ignore:line + } + } + + return errors; +} + +CodeMirror.registerHelper( 'lint', 'javascript', validator ); + +/** + * Gets the options for Espree from the supported JSHint options. + * + * @since 7.0.0 + * + * @param {SupportedJSHintOptions} options - Linting options for JSHint. + * @return {{ + * ecmaVersion?: number|'latest', + * ecmaFeatures?: { + * impliedStrict?: true + * } + * }} + */ +function getEspreeOptions( options ) { + const ecmaFeatures = {}; + if ( options.strict === 'implied' ) { + ecmaFeatures.impliedStrict = true; + } + + return { + ecmaVersion: getEcmaVersion( options ), + sourceType: options.module ? 'module' : 'script', + ecmaFeatures, + }; +} + +/** + * Gets the ECMAScript version. + * + * @since 7.0.0 + * + * @param {SupportedJSHintOptions} options - Options. + * @return {number|'latest'} ECMAScript version. + */ +function getEcmaVersion( options ) { + if ( typeof options.esversion === 'number' ) { + return options.esversion; + } + if ( options.es5 ) { + return 5; + } + if ( options.es3 ) { + return 3; + } + return 'latest'; +} diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index f5dacf28f7327..725f12b7c1b2b 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -4069,7 +4069,6 @@ function wp_enqueue_code_editor( $args ) { case 'text/x-php': wp_enqueue_script( 'htmlhint' ); wp_enqueue_script( 'csslint' ); - wp_enqueue_script( 'jshint' ); if ( ! current_user_can( 'unfiltered_html' ) ) { wp_enqueue_script( 'htmlhint-kses' ); } @@ -4081,7 +4080,6 @@ function wp_enqueue_code_editor( $args ) { case 'application/ld+json': case 'text/typescript': case 'application/typescript': - wp_enqueue_script( 'jshint' ); wp_enqueue_script( 'jsonlint' ); break; } @@ -4153,30 +4151,38 @@ function wp_get_code_editor_settings( $args ) { 'outline-none' => true, ), 'jshint' => array( - // The following are copied from . - 'boss' => true, - 'curly' => true, - 'eqeqeq' => true, - 'eqnull' => true, - 'es3' => true, - 'expr' => true, - 'immed' => true, - 'noarg' => true, - 'nonbsp' => true, - 'onevar' => true, - 'quotmark' => 'single', - 'trailing' => true, - 'undef' => true, - 'unused' => true, - - 'browser' => true, - - 'globals' => array( - '_' => false, - 'Backbone' => false, - 'jQuery' => false, - 'JSON' => false, - 'wp' => false, + 'esversion' => 11, + + // The following JSHint *linting rule* options are copied from + // . + // Parsing-related options such as `esversion` (and, in other contexts, `es5`, `es3`, `module`, `strict`) + // are honored by the Espree-based integration, but these linting-rule options are not interpreted by Espree + // and are kept only for compatibility/documentation with the original JSHint configuration. + 'boss' => true, + 'curly' => true, + 'eqeqeq' => true, + 'eqnull' => true, + 'expr' => true, + 'immed' => true, + 'noarg' => true, + 'nonbsp' => true, + 'quotmark' => 'single', + 'undef' => true, + 'unused' => true, + 'browser' => true, + 'globals' => array( + '_' => false, + 'Backbone' => false, + 'jQuery' => false, + 'JSON' => false, + 'wp' => false, + 'export' => false, + 'module' => false, + 'require' => false, + 'WorkerGlobalScope' => false, + 'self' => false, + 'OffscreenCanvas' => false, + 'Promise' => false, ), ), 'htmlhint' => array( diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 87689423c37ac..4e9de5a0a7ed9 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -1196,9 +1196,10 @@ function wp_default_scripts( $scripts ) { ); $scripts->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.65.20' ); + did_action( 'init' ) && $scripts->add_data( 'wp-codemirror', 'module_dependencies', array( 'espree' ) ); $scripts->add( 'csslint', '/wp-includes/js/codemirror/csslint.js', array(), '1.0.5' ); - $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.1' ); - $scripts->add( 'jshint', '/wp-includes/js/codemirror/fakejshint.js', array( 'esprima' ), '2.9.5' ); + $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.1' ); // Deprecated. Use 'espree' script module. + $scripts->add( 'jshint', '/wp-includes/js/codemirror/fakejshint.js', array( 'esprima' ), '2.9.5' ); // Deprecated. $scripts->add( 'jsonlint', '/wp-includes/js/codemirror/jsonlint.js', array(), '1.6.3' ); $scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '1.8.0' ); $scripts->add( 'htmlhint-kses', '/wp-includes/js/codemirror/htmlhint-kses.js', array( 'htmlhint' ) ); diff --git a/src/wp-includes/script-modules.php b/src/wp-includes/script-modules.php index ee91ee4361a7d..0a39efea1dc27 100644 --- a/src/wp-includes/script-modules.php +++ b/src/wp-includes/script-modules.php @@ -194,6 +194,13 @@ function wp_default_script_modules() { $module_deps = $script_module_data['module_dependencies'] ?? array(); wp_register_script_module( $script_module_id, $path, $module_deps, $script_module_data['version'], $args ); } + + wp_register_script_module( + 'espree', + includes_url( 'js/codemirror/espree.min.js' ), + array(), + '9.6.1' + ); } /** diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 995d46ad6ae61..b1d2f3b2db471 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -3158,14 +3158,12 @@ public function test_wp_enqueue_code_editor_when_php_file_will_be_passed() { 'curly', 'eqeqeq', 'eqnull', - 'es3', + 'esversion', 'expr', 'immed', 'noarg', 'nonbsp', - 'onevar', 'quotmark', - 'trailing', 'undef', 'unused', 'browser', @@ -3242,14 +3240,12 @@ public function test_wp_enqueue_code_editor_when_generated_array_by_compact_will 'curly', 'eqeqeq', 'eqnull', - 'es3', + 'esversion', 'expr', 'immed', 'noarg', 'nonbsp', - 'onevar', 'quotmark', - 'trailing', 'undef', 'unused', 'browser', @@ -3340,14 +3336,12 @@ public function test_wp_enqueue_code_editor_when_generated_array_by_array_merge_ 'curly', 'eqeqeq', 'eqnull', - 'es3', + 'esversion', 'expr', 'immed', 'noarg', 'nonbsp', - 'onevar', 'quotmark', - 'trailing', 'undef', 'unused', 'browser', @@ -3435,14 +3429,12 @@ public function test_wp_enqueue_code_editor_when_simple_array_will_be_passed() { 'curly', 'eqeqeq', 'eqnull', - 'es3', + 'esversion', 'expr', 'immed', 'noarg', 'nonbsp', - 'onevar', 'quotmark', - 'trailing', 'undef', 'unused', 'browser', @@ -4020,7 +4012,7 @@ static function ( $dependency ) { ); // Exclude packages that are not registered in WordPress. - $exclude = array( 'react-is', 'json2php' ); + $exclude = array( 'react-is', 'json2php', 'espree' ); $package_json_dependencies = array_diff( $package_json_dependencies, $exclude ); /* diff --git a/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php b/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php index 1a61d944719b6..c9377ba54e655 100644 --- a/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php +++ b/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php @@ -251,7 +251,6 @@ public function test_enqueue_admin_scripts_when_logged_in_and_syntax_highlightin $this->assertTrue( wp_script_is( 'code-editor', 'enqueued' ) ); $this->assertTrue( wp_script_is( 'wp-codemirror', 'enqueued' ) ); $this->assertTrue( wp_script_is( 'csslint', 'enqueued' ) ); - $this->assertTrue( wp_script_is( 'jshint', 'enqueued' ) ); $this->assertTrue( wp_script_is( 'htmlhint', 'enqueued' ) ); } diff --git a/tools/vendors/codemirror-entry.js b/tools/vendors/codemirror-entry.js index cf3b7523d0edf..a8856f55d11da 100644 --- a/tools/vendors/codemirror-entry.js +++ b/tools/vendors/codemirror-entry.js @@ -1,90 +1,91 @@ // Import CodeMirror core to be exposed as window.wp.CodeMirror. -var CodeMirror = require( 'codemirror/lib/codemirror' ); +import CodeMirror from 'codemirror/lib/codemirror'; // Keymaps -require( 'codemirror/keymap/emacs' ); -require( 'codemirror/keymap/sublime' ); -require( 'codemirror/keymap/vim' ); +import 'codemirror/keymap/emacs'; +import 'codemirror/keymap/sublime'; +import 'codemirror/keymap/vim'; // Addons (Hinting) -require( 'codemirror/addon/hint/show-hint' ); -require( 'codemirror/addon/hint/anyword-hint' ); -require( 'codemirror/addon/hint/css-hint' ); -require( 'codemirror/addon/hint/html-hint' ); -require( 'codemirror/addon/hint/javascript-hint' ); -require( 'codemirror/addon/hint/sql-hint' ); -require( 'codemirror/addon/hint/xml-hint' ); +import 'codemirror/addon/hint/show-hint'; +import 'codemirror/addon/hint/anyword-hint'; +import 'codemirror/addon/hint/css-hint'; +import 'codemirror/addon/hint/html-hint'; +import 'codemirror/addon/hint/javascript-hint'; +import 'codemirror/addon/hint/sql-hint'; +import 'codemirror/addon/hint/xml-hint'; // Addons (Linting) -require( 'codemirror/addon/lint/lint' ); -require( 'codemirror/addon/lint/css-lint' ); -require( 'codemirror/addon/lint/html-lint' ); -require( 'codemirror/addon/lint/javascript-lint' ); -require( 'codemirror/addon/lint/json-lint' ); +import 'codemirror/addon/lint/lint'; +import 'codemirror/addon/lint/css-lint'; +import 'codemirror/addon/lint/html-lint'; + +import '../../src/js/_enqueues/vendor/codemirror/javascript-lint'; +import 'codemirror/addon/lint/json-lint'; // Addons (Other) -require( 'codemirror/addon/comment/comment' ); -require( 'codemirror/addon/comment/continuecomment' ); -require( 'codemirror/addon/fold/xml-fold' ); -require( 'codemirror/addon/mode/overlay' ); -require( 'codemirror/addon/edit/closebrackets' ); -require( 'codemirror/addon/edit/closetag' ); -require( 'codemirror/addon/edit/continuelist' ); -require( 'codemirror/addon/edit/matchbrackets' ); -require( 'codemirror/addon/edit/matchtags' ); -require( 'codemirror/addon/edit/trailingspace' ); -require( 'codemirror/addon/dialog/dialog' ); -require( 'codemirror/addon/display/autorefresh' ); -require( 'codemirror/addon/display/fullscreen' ); -require( 'codemirror/addon/display/panel' ); -require( 'codemirror/addon/display/placeholder' ); -require( 'codemirror/addon/display/rulers' ); -require( 'codemirror/addon/fold/brace-fold' ); -require( 'codemirror/addon/fold/comment-fold' ); -require( 'codemirror/addon/fold/foldcode' ); -require( 'codemirror/addon/fold/foldgutter' ); -require( 'codemirror/addon/fold/indent-fold' ); -require( 'codemirror/addon/fold/markdown-fold' ); -require( 'codemirror/addon/merge/merge' ); -require( 'codemirror/addon/mode/loadmode' ); -require( 'codemirror/addon/mode/multiplex' ); -require( 'codemirror/addon/mode/simple' ); -require( 'codemirror/addon/runmode/runmode' ); -require( 'codemirror/addon/runmode/colorize' ); -require( 'codemirror/addon/runmode/runmode-standalone' ); -require( 'codemirror/addon/scroll/annotatescrollbar' ); -require( 'codemirror/addon/scroll/scrollpastend' ); -require( 'codemirror/addon/scroll/simplescrollbars' ); -require( 'codemirror/addon/search/search' ); -require( 'codemirror/addon/search/jump-to-line' ); -require( 'codemirror/addon/search/match-highlighter' ); -require( 'codemirror/addon/search/matchesonscrollbar' ); -require( 'codemirror/addon/search/searchcursor' ); -require( 'codemirror/addon/tern/tern' ); -require( 'codemirror/addon/tern/worker' ); -require( 'codemirror/addon/wrap/hardwrap' ); -require( 'codemirror/addon/selection/active-line' ); -require( 'codemirror/addon/selection/mark-selection' ); -require( 'codemirror/addon/selection/selection-pointer' ); +import 'codemirror/addon/comment/comment'; +import 'codemirror/addon/comment/continuecomment'; +import 'codemirror/addon/fold/xml-fold'; +import 'codemirror/addon/mode/overlay'; +import 'codemirror/addon/edit/closebrackets'; +import 'codemirror/addon/edit/closetag'; +import 'codemirror/addon/edit/continuelist'; +import 'codemirror/addon/edit/matchbrackets'; +import 'codemirror/addon/edit/matchtags'; +import 'codemirror/addon/edit/trailingspace'; +import 'codemirror/addon/dialog/dialog'; +import 'codemirror/addon/display/autorefresh'; +import 'codemirror/addon/display/fullscreen'; +import 'codemirror/addon/display/panel'; +import 'codemirror/addon/display/placeholder'; +import 'codemirror/addon/display/rulers'; +import 'codemirror/addon/fold/brace-fold'; +import 'codemirror/addon/fold/comment-fold'; +import 'codemirror/addon/fold/foldcode'; +import 'codemirror/addon/fold/foldgutter'; +import 'codemirror/addon/fold/indent-fold'; +import 'codemirror/addon/fold/markdown-fold'; +import 'codemirror/addon/merge/merge'; +import 'codemirror/addon/mode/loadmode'; +import 'codemirror/addon/mode/multiplex'; +import 'codemirror/addon/mode/simple'; +import 'codemirror/addon/runmode/runmode'; +import 'codemirror/addon/runmode/colorize'; +import 'codemirror/addon/runmode/runmode-standalone'; +import 'codemirror/addon/scroll/annotatescrollbar'; +import 'codemirror/addon/scroll/scrollpastend'; +import 'codemirror/addon/scroll/simplescrollbars'; +import 'codemirror/addon/search/search'; +import 'codemirror/addon/search/jump-to-line'; +import 'codemirror/addon/search/match-highlighter'; +import 'codemirror/addon/search/matchesonscrollbar'; +import 'codemirror/addon/search/searchcursor'; +import 'codemirror/addon/tern/tern'; +import 'codemirror/addon/tern/worker'; +import 'codemirror/addon/wrap/hardwrap'; +import 'codemirror/addon/selection/active-line'; +import 'codemirror/addon/selection/mark-selection'; +import 'codemirror/addon/selection/selection-pointer'; // Modes -require( 'codemirror/mode/meta' ); -require( 'codemirror/mode/clike/clike' ); -require( 'codemirror/mode/css/css' ); -require( 'codemirror/mode/diff/diff' ); -require( 'codemirror/mode/htmlmixed/htmlmixed' ); -require( 'codemirror/mode/http/http' ); -require( 'codemirror/mode/javascript/javascript' ); -require( 'codemirror/mode/jsx/jsx' ); -require( 'codemirror/mode/markdown/markdown' ); -require( 'codemirror/mode/gfm/gfm' ); -require( 'codemirror/mode/nginx/nginx' ); -require( 'codemirror/mode/php/php' ); -require( 'codemirror/mode/sass/sass' ); -require( 'codemirror/mode/shell/shell' ); -require( 'codemirror/mode/sql/sql' ); -require( 'codemirror/mode/xml/xml' ); -require( 'codemirror/mode/yaml/yaml' ); +import 'codemirror/mode/meta'; +import 'codemirror/mode/clike/clike'; +import 'codemirror/mode/css/css'; +import 'codemirror/mode/diff/diff'; +import 'codemirror/mode/htmlmixed/htmlmixed'; +import 'codemirror/mode/http/http'; +import 'codemirror/mode/javascript/javascript'; +import 'codemirror/mode/jsx/jsx'; +import 'codemirror/mode/markdown/markdown'; +import 'codemirror/mode/gfm/gfm'; +import 'codemirror/mode/nginx/nginx'; +import 'codemirror/mode/php/php'; +import 'codemirror/mode/sass/sass'; +import 'codemirror/mode/shell/shell'; +import 'codemirror/mode/sql/sql'; +import 'codemirror/mode/xml/xml'; +import 'codemirror/mode/yaml/yaml'; /** * Please note that the codemirror-standalone "runmode" addon is setting `window.CodeMirror` diff --git a/tools/webpack/codemirror.config.js b/tools/webpack/codemirror.config.js index aac048dccc1ef..b6e99dd289daf 100644 --- a/tools/webpack/codemirror.config.js +++ b/tools/webpack/codemirror.config.js @@ -6,32 +6,36 @@ const codemirrorBanner = require( './codemirror-banner' ); module.exports = ( env = { buildTarget: 'src/' } ) => { const buildTarget = env.buildTarget || 'src/'; + const outputPath = path.resolve( __dirname, '../../', buildTarget, 'wp-includes/js/codemirror' ); - return { + const optimization = { + minimize: true, + minimizer: [ + new TerserPlugin( { + terserOptions: { + format: { + comments: /^!/, + }, + }, + extractComments: false, + } ), + ], + }; + + const codemirrorConfig = { target: 'browserslist', mode: 'production', - entry: './tools/vendors/codemirror-entry.js', - output: { - path: path.resolve( __dirname, '../../', buildTarget, 'wp-includes/js/codemirror' ), - filename: 'codemirror.min.js', + entry: { + 'codemirror.min': './tools/vendors/codemirror-entry.js', }, - optimization: { - minimize: true, - minimizer: [ - new TerserPlugin( { - terserOptions: { - format: { - comments: /^!/, - }, - }, - extractComments: false, - } ), - ], + output: { + path: outputPath, + filename: '[name].js', }, + optimization, externals: { 'csslint': 'window.CSSLint', 'htmlhint': 'window.HTMLHint', - 'jshint': 'window.JSHINT', 'jsonlint': 'window.jsonlint', }, plugins: [ @@ -42,4 +46,25 @@ module.exports = ( env = { buildTarget: 'src/' } ) => { } ), ], }; + + const espreeConfig = { + target: 'browserslist', + mode: 'production', + entry: { + 'espree.min': 'espree', + }, + output: { + path: outputPath, + filename: '[name].js', + library: { + type: 'module', + }, + }, + experiments: { + outputModule: true, + }, + optimization, + }; + + return [ codemirrorConfig, espreeConfig ]; };