Make WordPress Core

Changeset 61611


Ignore:
Timestamp:
02/10/2026 10:29:49 PM (8 weeks ago)
Author:
westonruter
Message:

Code Editor: Switch from Esprima to Espree for JavaScript linting in CodeMirror.

Esprima is no longer maintained, and it does not support the latest JavaScript features in ES11, as Espree does.

  • New Linter Integration: Introduces src/js/_enqueues/vendor/codemirror/javascript-lint.js using espree for parsing and error reporting, replacing the dependency on jshint and esprima scripts.
  • Script Modules: Registers espree as a script module and leverages the module_dependencies argument in wp_register_script() to ensure espree is available as a dynamic import.
  • Editor Settings: Updates wp_get_code_editor_settings() to use ES11 (ECMAScript 2020) defaults and synchronizes JSHint settings from .jshintrc for compatibility.
  • Editable Extensions: Adds .mjs to the list of editable file extensions for plugins and themes.
  • Deprecations: Marks esprima and jshint script handles as deprecated.
  • Build Tools: Updates Webpack configuration to bundle espree as a module and use the new local javascript-lint.js.

Developed in https://github.com/WordPress/wordpress-develop/pull/10806

Follow-up to [61587], [61544], [61539], [42547].

Props westonruter, jonsurrell.
See #64562, #61500, #48456, #42850.
Fixes #64558.

Location:
trunk
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/package-lock.json

    r61539 r61611  
    1717                "csslint": "1.0.5",
    1818                "element-closest": "3.0.2",
     19                "espree": "9.6.1",
    1920                "esprima": "4.0.1",
    2021                "formdata-polyfill": "4.0.10",
     
    4546                "@playwright/test": "1.56.1",
    4647                "@pmmmwh/react-refresh-webpack-plugin": "0.6.1",
     48                "@types/codemirror": "5.60.17",
    4749                "@wordpress/e2e-test-utils-playwright": "1.33.2",
    4850                "@wordpress/prettier-config": "4.33.1",
     
    51325134            }
    51335135        },
     5136        "node_modules/@types/codemirror": {
     5137            "version": "5.60.17",
     5138            "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.17.tgz",
     5139            "integrity": "sha512-AZq2FIsUHVMlp7VSe2hTfl5w4pcUkoFkM3zVsRKsn1ca8CXRDYvnin04+HP2REkwsxemuHqvDofdlhUWNpbwfw==",
     5140            "dev": true,
     5141            "license": "MIT",
     5142            "dependencies": {
     5143                "@types/tern": "*"
     5144            }
     5145        },
    51345146        "node_modules/@types/connect": {
    51355147            "version": "3.4.38",
     
    54205432            "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
    54215433            "dev": true
     5434        },
     5435        "node_modules/@types/tern": {
     5436            "version": "0.23.9",
     5437            "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz",
     5438            "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==",
     5439            "dev": true,
     5440            "license": "MIT",
     5441            "dependencies": {
     5442                "@types/estree": "*"
     5443            }
    54225444        },
    54235445        "node_modules/@types/tough-cookie": {
     
    74467468            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
    74477469            "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
    7448             "dev": true,
    74497470            "license": "MIT",
    74507471            "bin": {
     
    74697490            "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
    74707491            "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
    7471             "dev": true,
    74727492            "peerDependencies": {
    74737493                "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
     
    1328613306            "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
    1328713307            "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
    13288             "dev": true,
    1328913308            "dependencies": {
    1329013309                "acorn": "^8.9.0",
     
    1330313322            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
    1330413323            "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
    13305             "dev": true,
    1330613324            "license": "Apache-2.0",
    1330713325            "engines": {
  • trunk/package.json

    r61605 r61611  
    3131        "@playwright/test": "1.56.1",
    3232        "@pmmmwh/react-refresh-webpack-plugin": "0.6.1",
     33        "@types/codemirror": "5.60.17",
    3334        "@wordpress/e2e-test-utils-playwright": "1.33.2",
    3435        "@wordpress/prettier-config": "4.33.1",
     
    8081        "csslint": "1.0.5",
    8182        "element-closest": "3.0.2",
     83        "espree": "9.6.1",
    8284        "esprima": "4.0.1",
    8385        "formdata-polyfill": "4.0.10",
  • trunk/src/wp-admin/includes/file.php

    r61470 r61611  
    203203        'include',
    204204        'js',
     205        'mjs',
    205206        'json',
    206207        'jsx',
     
    262263        'include',
    263264        'js',
     265        'mjs',
    264266        'json',
    265267        'jsx',
  • trunk/src/wp-includes/general-template.php

    r61497 r61611  
    40704070                    wp_enqueue_script( 'htmlhint' );
    40714071                    wp_enqueue_script( 'csslint' );
    4072                     wp_enqueue_script( 'jshint' );
    40734072                    if ( ! current_user_can( 'unfiltered_html' ) ) {
    40744073                        wp_enqueue_script( 'htmlhint-kses' );
     
    40824081                case 'text/typescript':
    40834082                case 'application/typescript':
    4084                     wp_enqueue_script( 'jshint' );
    40854083                    wp_enqueue_script( 'jsonlint' );
    40864084                    break;
     
    41544152        ),
    41554153        'jshint'     => array(
    4156             // The following are copied from <https://github.com/WordPress/wordpress-develop/blob/4.8.1/.jshintrc>.
    4157             'boss'     => true,
    4158             'curly'    => true,
    4159             'eqeqeq'   => true,
    4160             'eqnull'   => true,
    4161             'es3'      => true,
    4162             'expr'     => true,
    4163             'immed'    => true,
    4164             'noarg'    => true,
    4165             'nonbsp'   => true,
    4166             'onevar'   => true,
    4167             'quotmark' => 'single',
    4168             'trailing' => true,
    4169             'undef'    => true,
    4170             'unused'   => true,
    4171 
    4172             'browser'  => true,
    4173 
    4174             'globals'  => array(
    4175                 '_'        => false,
    4176                 'Backbone' => false,
    4177                 'jQuery'   => false,
    4178                 'JSON'     => false,
    4179                 'wp'       => false,
     4154            'esversion' => 11,
     4155            'module'    => str_ends_with( $args['file'] ?? '', '.mjs' ),
     4156
     4157            // The following JSHint *linting rule* options are copied from
     4158            // <https://github.com/WordPress/wordpress-develop/blob/6.9.0/.jshintrc>.
     4159            // Parsing-related options such as `esversion` (and, in other contexts, `es5`, `es3`, `module`, `strict`)
     4160            // are honored by the Espree-based integration, but these linting-rule options are not interpreted by Espree
     4161            // and are kept only for compatibility/documentation with the original JSHint configuration.
     4162            'boss'      => true,
     4163            'curly'     => true,
     4164            'eqeqeq'    => true,
     4165            'eqnull'    => true,
     4166            'expr'      => true,
     4167            'immed'     => true,
     4168            'noarg'     => true,
     4169            'nonbsp'    => true,
     4170            'quotmark'  => 'single',
     4171            'undef'     => true,
     4172            'unused'    => true,
     4173            'browser'   => true,
     4174            'globals'   => array(
     4175                '_'                 => false,
     4176                'Backbone'          => false,
     4177                'jQuery'            => false,
     4178                'JSON'              => false,
     4179                'wp'                => false,
     4180                'export'            => false,
     4181                'module'            => false,
     4182                'require'           => false,
     4183                'WorkerGlobalScope' => false,
     4184                'self'              => false,
     4185                'OffscreenCanvas'   => false,
     4186                'Promise'           => false,
    41804187            ),
    41814188        ),
     
    42344241                    break;
    42354242                case 'js':
     4243                case 'mjs':
    42364244                    $type = 'text/javascript';
    42374245                    break;
  • trunk/src/wp-includes/script-loader.php

    r61554 r61611  
    11971197
    11981198    $scripts->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.65.20' );
     1199    did_action( 'init' ) && $scripts->add_data( 'wp-codemirror', 'module_dependencies', array( 'espree' ) );
    11991200    $scripts->add( 'csslint', '/wp-includes/js/codemirror/csslint.js', array(), '1.0.5' );
    1200     $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.1' );
    1201     $scripts->add( 'jshint', '/wp-includes/js/codemirror/fakejshint.js', array( 'esprima' ), '2.9.5' );
     1201    $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.1' ); // Deprecated. Use 'espree' script module.
     1202    $scripts->add( 'jshint', '/wp-includes/js/codemirror/fakejshint.js', array( 'esprima' ), '2.9.5' ); // Deprecated.
    12021203    $scripts->add( 'jsonlint', '/wp-includes/js/codemirror/jsonlint.js', array(), '1.6.3' );
    12031204    $scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '1.8.0' );
  • trunk/src/wp-includes/script-modules.php

    r61587 r61611  
    195195        wp_register_script_module( $script_module_id, $path, $module_deps, $script_module_data['version'], $args );
    196196    }
     197
     198    wp_register_script_module(
     199        'espree',
     200        includes_url( 'js/codemirror/espree.min.js' ),
     201        array(),
     202        '9.6.1'
     203    );
    197204}
    198205
  • trunk/tests/phpunit/tests/dependencies/scripts.php

    r61587 r61611  
    31593159                'eqeqeq',
    31603160                'eqnull',
    3161                 'es3',
     3161                'esversion',
    31623162                'expr',
    31633163                'immed',
     3164                'module',
    31643165                'noarg',
    31653166                'nonbsp',
    3166                 'onevar',
    31673167                'quotmark',
    3168                 'trailing',
    31693168                'undef',
    31703169                'unused',
     
    32433242                'eqeqeq',
    32443243                'eqnull',
    3245                 'es3',
     3244                'esversion',
    32463245                'expr',
    32473246                'immed',
     3247                'module',
    32483248                'noarg',
    32493249                'nonbsp',
    3250                 'onevar',
    32513250                'quotmark',
    3252                 'trailing',
    32533251                'undef',
    32543252                'unused',
     
    33413339                'eqeqeq',
    33423340                'eqnull',
    3343                 'es3',
     3341                'esversion',
    33443342                'expr',
    33453343                'immed',
     3344                'module',
    33463345                'noarg',
    33473346                'nonbsp',
    3348                 'onevar',
    33493347                'quotmark',
    3350                 'trailing',
    33513348                'undef',
    33523349                'unused',
     
    34363433                'eqeqeq',
    34373434                'eqnull',
    3438                 'es3',
     3435                'esversion',
    34393436                'expr',
    34403437                'immed',
     3438                'module',
    34413439                'noarg',
    34423440                'nonbsp',
    3443                 'onevar',
    34443441                'quotmark',
    3445                 'trailing',
    34463442                'undef',
    34473443                'unused',
     
    40214017
    40224018        // Exclude packages that are not registered in WordPress.
    4023         $exclude                   = array( 'react-is', 'json2php' );
     4019        $exclude                   = array( 'react-is', 'json2php', 'espree' );
    40244020        $package_json_dependencies = array_diff( $package_json_dependencies, $exclude );
    40254021
  • trunk/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php

    r59120 r61611  
    252252        $this->assertTrue( wp_script_is( 'wp-codemirror', 'enqueued' ) );
    253253        $this->assertTrue( wp_script_is( 'csslint', 'enqueued' ) );
    254         $this->assertTrue( wp_script_is( 'jshint', 'enqueued' ) );
    255254        $this->assertTrue( wp_script_is( 'htmlhint', 'enqueued' ) );
    256255    }
  • trunk/tools/vendors/codemirror-entry.js

    r61539 r61611  
    11// Import CodeMirror core to be exposed as window.wp.CodeMirror.
    2 var CodeMirror = require( 'codemirror/lib/codemirror' );
     2import CodeMirror from 'codemirror/lib/codemirror';
    33
    44// Keymaps
    5 require( 'codemirror/keymap/emacs' );
    6 require( 'codemirror/keymap/sublime' );
    7 require( 'codemirror/keymap/vim' );
     5import 'codemirror/keymap/emacs';
     6import 'codemirror/keymap/sublime';
     7import 'codemirror/keymap/vim';
    88
    99// Addons (Hinting)
    10 require( 'codemirror/addon/hint/show-hint' );
    11 require( 'codemirror/addon/hint/anyword-hint' );
    12 require( 'codemirror/addon/hint/css-hint' );
    13 require( 'codemirror/addon/hint/html-hint' );
    14 require( 'codemirror/addon/hint/javascript-hint' );
    15 require( 'codemirror/addon/hint/sql-hint' );
    16 require( 'codemirror/addon/hint/xml-hint' );
     10import 'codemirror/addon/hint/show-hint';
     11import 'codemirror/addon/hint/anyword-hint';
     12import 'codemirror/addon/hint/css-hint';
     13import 'codemirror/addon/hint/html-hint';
     14import 'codemirror/addon/hint/javascript-hint';
     15import 'codemirror/addon/hint/sql-hint';
     16import 'codemirror/addon/hint/xml-hint';
    1717
    1818// Addons (Linting)
    19 require( 'codemirror/addon/lint/lint' );
    20 require( 'codemirror/addon/lint/css-lint' );
    21 require( 'codemirror/addon/lint/html-lint' );
    22 require( 'codemirror/addon/lint/javascript-lint' );
    23 require( 'codemirror/addon/lint/json-lint' );
     19import 'codemirror/addon/lint/lint';
     20import 'codemirror/addon/lint/css-lint';
     21import 'codemirror/addon/lint/html-lint';
     22
     23import '../../src/js/_enqueues/vendor/codemirror/javascript-lint';
     24import 'codemirror/addon/lint/json-lint';
    2425
    2526// Addons (Other)
    26 require( 'codemirror/addon/comment/comment' );
    27 require( 'codemirror/addon/comment/continuecomment' );
    28 require( 'codemirror/addon/fold/xml-fold' );
    29 require( 'codemirror/addon/mode/overlay' );
    30 require( 'codemirror/addon/edit/closebrackets' );
    31 require( 'codemirror/addon/edit/closetag' );
    32 require( 'codemirror/addon/edit/continuelist' );
    33 require( 'codemirror/addon/edit/matchbrackets' );
    34 require( 'codemirror/addon/edit/matchtags' );
    35 require( 'codemirror/addon/edit/trailingspace' );
    36 require( 'codemirror/addon/dialog/dialog' );
    37 require( 'codemirror/addon/display/autorefresh' );
    38 require( 'codemirror/addon/display/fullscreen' );
    39 require( 'codemirror/addon/display/panel' );
    40 require( 'codemirror/addon/display/placeholder' );
    41 require( 'codemirror/addon/display/rulers' );
    42 require( 'codemirror/addon/fold/brace-fold' );
    43 require( 'codemirror/addon/fold/comment-fold' );
    44 require( 'codemirror/addon/fold/foldcode' );
    45 require( 'codemirror/addon/fold/foldgutter' );
    46 require( 'codemirror/addon/fold/indent-fold' );
    47 require( 'codemirror/addon/fold/markdown-fold' );
    48 require( 'codemirror/addon/merge/merge' );
    49 require( 'codemirror/addon/mode/loadmode' );
    50 require( 'codemirror/addon/mode/multiplex' );
    51 require( 'codemirror/addon/mode/simple' );
    52 require( 'codemirror/addon/runmode/runmode' );
    53 require( 'codemirror/addon/runmode/colorize' );
    54 require( 'codemirror/addon/runmode/runmode-standalone' );
    55 require( 'codemirror/addon/scroll/annotatescrollbar' );
    56 require( 'codemirror/addon/scroll/scrollpastend' );
    57 require( 'codemirror/addon/scroll/simplescrollbars' );
    58 require( 'codemirror/addon/search/search' );
    59 require( 'codemirror/addon/search/jump-to-line' );
    60 require( 'codemirror/addon/search/match-highlighter' );
    61 require( 'codemirror/addon/search/matchesonscrollbar' );
    62 require( 'codemirror/addon/search/searchcursor' );
    63 require( 'codemirror/addon/tern/tern' );
    64 require( 'codemirror/addon/tern/worker' );
    65 require( 'codemirror/addon/wrap/hardwrap' );
    66 require( 'codemirror/addon/selection/active-line' );
    67 require( 'codemirror/addon/selection/mark-selection' );
    68 require( 'codemirror/addon/selection/selection-pointer' );
     27import 'codemirror/addon/comment/comment';
     28import 'codemirror/addon/comment/continuecomment';
     29import 'codemirror/addon/fold/xml-fold';
     30import 'codemirror/addon/mode/overlay';
     31import 'codemirror/addon/edit/closebrackets';
     32import 'codemirror/addon/edit/closetag';
     33import 'codemirror/addon/edit/continuelist';
     34import 'codemirror/addon/edit/matchbrackets';
     35import 'codemirror/addon/edit/matchtags';
     36import 'codemirror/addon/edit/trailingspace';
     37import 'codemirror/addon/dialog/dialog';
     38import 'codemirror/addon/display/autorefresh';
     39import 'codemirror/addon/display/fullscreen';
     40import 'codemirror/addon/display/panel';
     41import 'codemirror/addon/display/placeholder';
     42import 'codemirror/addon/display/rulers';
     43import 'codemirror/addon/fold/brace-fold';
     44import 'codemirror/addon/fold/comment-fold';
     45import 'codemirror/addon/fold/foldcode';
     46import 'codemirror/addon/fold/foldgutter';
     47import 'codemirror/addon/fold/indent-fold';
     48import 'codemirror/addon/fold/markdown-fold';
     49import 'codemirror/addon/merge/merge';
     50import 'codemirror/addon/mode/loadmode';
     51import 'codemirror/addon/mode/multiplex';
     52import 'codemirror/addon/mode/simple';
     53import 'codemirror/addon/runmode/runmode';
     54import 'codemirror/addon/runmode/colorize';
     55import 'codemirror/addon/runmode/runmode-standalone';
     56import 'codemirror/addon/scroll/annotatescrollbar';
     57import 'codemirror/addon/scroll/scrollpastend';
     58import 'codemirror/addon/scroll/simplescrollbars';
     59import 'codemirror/addon/search/search';
     60import 'codemirror/addon/search/jump-to-line';
     61import 'codemirror/addon/search/match-highlighter';
     62import 'codemirror/addon/search/matchesonscrollbar';
     63import 'codemirror/addon/search/searchcursor';
     64import 'codemirror/addon/tern/tern';
     65import 'codemirror/addon/tern/worker';
     66import 'codemirror/addon/wrap/hardwrap';
     67import 'codemirror/addon/selection/active-line';
     68import 'codemirror/addon/selection/mark-selection';
     69import 'codemirror/addon/selection/selection-pointer';
    6970
    7071// Modes
    71 require( 'codemirror/mode/meta' );
    72 require( 'codemirror/mode/clike/clike' );
    73 require( 'codemirror/mode/css/css' );
    74 require( 'codemirror/mode/diff/diff' );
    75 require( 'codemirror/mode/htmlmixed/htmlmixed' );
    76 require( 'codemirror/mode/http/http' );
    77 require( 'codemirror/mode/javascript/javascript' );
    78 require( 'codemirror/mode/jsx/jsx' );
    79 require( 'codemirror/mode/markdown/markdown' );
    80 require( 'codemirror/mode/gfm/gfm' );
    81 require( 'codemirror/mode/nginx/nginx' );
    82 require( 'codemirror/mode/php/php' );
    83 require( 'codemirror/mode/sass/sass' );
    84 require( 'codemirror/mode/shell/shell' );
    85 require( 'codemirror/mode/sql/sql' );
    86 require( 'codemirror/mode/xml/xml' );
    87 require( 'codemirror/mode/yaml/yaml' );
     72import 'codemirror/mode/meta';
     73import 'codemirror/mode/clike/clike';
     74import 'codemirror/mode/css/css';
     75import 'codemirror/mode/diff/diff';
     76import 'codemirror/mode/htmlmixed/htmlmixed';
     77import 'codemirror/mode/http/http';
     78import 'codemirror/mode/javascript/javascript';
     79import 'codemirror/mode/jsx/jsx';
     80import 'codemirror/mode/markdown/markdown';
     81import 'codemirror/mode/gfm/gfm';
     82import 'codemirror/mode/nginx/nginx';
     83import 'codemirror/mode/php/php';
     84import 'codemirror/mode/sass/sass';
     85import 'codemirror/mode/shell/shell';
     86import 'codemirror/mode/sql/sql';
     87import 'codemirror/mode/xml/xml';
     88import 'codemirror/mode/yaml/yaml';
    8889
    8990/**
  • trunk/tools/webpack/codemirror.config.js

    r61544 r61611  
    77module.exports = ( env = { buildTarget: 'src/' } ) => {
    88    const buildTarget = env.buildTarget || 'src/';
     9    const outputPath = path.resolve( __dirname, '../../', buildTarget, 'wp-includes/js/codemirror' );
    910
    10     return {
     11    const optimization = {
     12        minimize: true,
     13        minimizer: [
     14            new TerserPlugin( {
     15                terserOptions: {
     16                    format: {
     17                        comments: /^!/,
     18                    },
     19                },
     20                extractComments: false,
     21            } ),
     22        ],
     23    };
     24
     25    const codemirrorConfig = {
    1126        target: 'browserslist',
    1227        mode: 'production',
    13         entry: './tools/vendors/codemirror-entry.js',
     28        entry: {
     29            'codemirror.min': './tools/vendors/codemirror-entry.js',
     30        },
    1431        output: {
    15             path: path.resolve( __dirname, '../../', buildTarget, 'wp-includes/js/codemirror' ),
    16             filename: 'codemirror.min.js',
     32            path: outputPath,
     33            filename: '[name].js',
    1734        },
    18         optimization: {
    19             minimize: true,
    20             minimizer: [
    21                 new TerserPlugin( {
    22                     terserOptions: {
    23                         format: {
    24                             comments: /^!/,
    25                         },
    26                     },
    27                     extractComments: false,
    28                 } ),
    29             ],
    30         },
     35        optimization,
    3136        externals: {
    3237            'csslint': 'window.CSSLint',
    3338            'htmlhint': 'window.HTMLHint',
    34             'jshint': 'window.JSHINT',
    3539            'jsonlint': 'window.jsonlint',
    3640        },
     
    4347        ],
    4448    };
     49
     50    const espreeConfig = {
     51        target: 'browserslist',
     52        mode: 'production',
     53        entry: {
     54            'espree.min': 'espree',
     55        },
     56        output: {
     57            path: outputPath,
     58            filename: '[name].js',
     59            library: {
     60                type: 'module',
     61            },
     62        },
     63        experiments: {
     64            outputModule: true,
     65        },
     66        optimization,
     67    };
     68
     69    return [ codemirrorConfig, espreeConfig ];
    4570};
Note: See TracChangeset for help on using the changeset viewer.