• Benjamin Franzke's avatar
    [TASK] Migrate backend TypeScript to ECMAScript modules (ESM) · 47481cbd
    Benjamin Franzke authored
    Use the JavaScript module and importmap Feature introduced
    in #96510 to import JavaScript as native browser modules
    (commonly referred to as ES6 modules, or short ESM).
    To be specific: we actually use ES2020 (ES11) modules,
    as we import modules dynamically via import() in
    combination with an importmap (#96510).
    
    Backwards compatibility for existing RequireJS imports
    is provided by a shim as introduced in #96510.
    
    How to (re)view this change
    ---------------------------
    
    Exclude all automatic TypeScript/JavaScript/lockfile changes with:
    
    git show --oneline -- . \
        ':(exclude)typo3/sysext/*.js' \
        ':(exclude)Build/Sources/TypeScript/*.ts' \
        ':(exclude)Build/yarn.lock'
    
    git show --oneline -- $(find Build/ \
        -name DragUploader.ts -o \
        -name FormEngine.ts -o \
        -name Helper.ts -o \
        -name CKEditorLoader.ts -o \
        -name CodeMirrorElement.ts)
    
    Gruntfile & tsconfig.json
    -------------------------
    
    Gruntfile is adapted to transform all our dependencies into ES6
    modules.
    
    Also tsconfig is adapted to emit es2020 modules (es2020 is required
    for dynamic module imports with import()).
    Also allowSyntheticDefaultImports is enabled while esModuleInterop
    is now longer needed as we target ES modules and therefore removed.
    allowSyntheticDefaultImports had been enabled implicitly by
    esModuleInterop, we still need this enabled as the type declarations
    of our dependencies still imply AMD/CJS exports
    (which we fix in our build steps).
    
    JSUnit
    ------
    
    JSUnit configuration is moved from testing-framework into core for more
    flexibility when adaptions are required. The testing is revamped
    to use karma-rollup-preprocessor instead of karma-requirejs in
    order to support the newly compiled ES6 modules.
    
    TypeScript Exports and Imports
    ------------------------------
    
    All export and import definitions have been auto-converted
    from AMD pseudo import/exports to native ES6 import/exports.
    
    Executed commands:
    
      find Build/Sources/TypeScript/ -name '*.ts' -exec sed -i \
        -e 's/export =/export default/' \
        -e 's/ = require(\(.*\))/ from \1/g' \
        -e "s/^import 'tablesort';/import Tablesort from 'tablesort';/" \
        '{}' +
    
    Note that the switch from `export =` to `export default` is
    not considered breaking because the require-adapter in
    requirejs-loader wil transparently resolve the .default in moduls.
    This is possible because AMD modules could not use `export =`
    and `export {}` (for named exports) at the same time.
    
    Explicitly use RequireJS for CodeMirror and ext:form for now
    ------------------------------------------------------------
    
    CodeMirror can't be easily transformed to ES6 right now,
    therefore this patch explicitly configures to use the
    global RequireJS instance.
    
    The ext:form JavaScript is currently not written in TypeScript
    and will therefore not be automatically transformed from AND
    to ES6 when updating tsconfig.json to emit ES6 modules.
    Therefore requirejs is uses.
    
    This partially reverts #96326 which changed some require()
    calls to import() syntax too early.
    
    New npm dependencies:
    ---------------------
    
     # For module-postprocessing in Gruntfile
     # This is the same parser as used for the
     # frontend polyfill es-module-shims
    yarn add --dev es-module-lexer
    
     # A rollup bundle for unit testing in karma is created
     # usin a karma preprocessor
    yarn remove karma-requirejs
    yarn add --dev karma-rollup-preprocessor rollup-plugin-glob-import
    
     # Update grunt-terser to support es2020 syntax
     # (uses terser v5 which we already depended on, but grunt v1
     # used the older v4 version)
    yarn add --dev grunt-terser@^2.0.0
    
    Releases: main
    Resolves: #96511
    Related: #96510
    Related: #96323
    Change-Id: Id1a6d414c1e9b2e39227d0b6ce9e79333a372349
    Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72637
    
    
    Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
    Tested-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
    Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
    Tested-by: Benjamin Franzke's avatarBenjamin Franzke <bfr@qbus.de>
    Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
    Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
    Reviewed-by: Benjamin Franzke's avatarBenjamin Franzke <bfr@qbus.de>
    47481cbd