Browse Source

feat(cli.js): readd ESM distribution (#2468)

Lucas Fernandes Nogueira 4 years ago
parent
commit
8d1fe0ea05

+ 5 - 0
.changes/readd-esm-cli.js.md

@@ -0,0 +1,5 @@
+---
+"cli.js": patch
+---
+
+The CLI is now an ES module and requires at least Node.js v12.20. Fixed previous releases by using Rollup instead of Webpack.

+ 0 - 0
tooling/cli.js/.eslintrc.js → tooling/cli.js/.eslintrc.cjs


+ 0 - 0
tooling/cli.js/.prettierrc.js → tooling/cli.js/.prettierrc.cjs


+ 1 - 1
tooling/cli.js/babel.config.js → tooling/cli.js/babel.config.cjs

@@ -6,7 +6,7 @@ module.exports = {
         targets: {
           node: 'current'
         },
-        modules: 'commonjs'
+        modules: false
       }
     ],
     '@babel/preset-typescript'

+ 5 - 5
tooling/cli.js/bin/tauri-deps.js

@@ -2,12 +2,12 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-License-Identifier: MIT
 
-async function run() {
-  const {
-    installDependencies,
-    updateDependencies
-  } = require('../dist/api/dependency-manager')
+import {
+  installDependencies,
+  updateDependencies
+} from '../dist/api/dependency-manager.js'
 
+async function run() {
   const choice = process.argv[2]
   if (choice === 'install') {
     await installDependencies()

+ 2 - 2
tooling/cli.js/bin/tauri-icon.js

@@ -2,8 +2,8 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-License-Identifier: MIT
 
-const parseArgs = require('minimist')
-const { tauricon } = require('../dist/api/tauricon')
+import parseArgs from 'minimist'
+import tauricon from '../dist/api/tauricon.js'
 
 /**
  * @type {object}

+ 10 - 11
tooling/cli.js/bin/tauri.js

@@ -3,9 +3,11 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-License-Identifier: MIT
 
-const chalk = require('chalk')
+import chalk from 'chalk'
+import updateNotifier from 'update-notifier'
+import { createRequire } from 'module'
+const require = createRequire(import.meta.url)
 const pkg = require('../package.json')
-const updateNotifier = require('update-notifier')
 
 const cmds = ['icon', 'deps']
 const rustCliCmds = ['dev', 'build', 'init', 'info', 'sign']
@@ -66,9 +68,9 @@ ${chalk.yellow('Options')}
       process.argv.splice(2, 1)
     }
     console.log(`[tauri]: running ${command}`)
-    require(`./tauri-${command}`)
+    await import(`./tauri-${command}.js`)
   } else {
-    const { runOnRustCli } = require('../dist/helpers/rust-cli')
+    const { runOnRustCli } = await import('../dist/helpers/rust-cli.js')
     if (process.argv && process.env.NODE_ENV !== 'test') {
       process.argv.splice(0, 3)
     }
@@ -80,19 +82,16 @@ ${chalk.yellow('Options')}
     ).promise
       .then(() => {
         if (command === 'init' && !process.argv.some((arg) => arg === '--ci')) {
-          const {
-            installDependencies
-          } = require('../dist/api/dependency-manager')
-          return installDependencies()
+          return import('../dist/api/dependency-manager.js').then(
+            ({ installDependencies }) => installDependencies()
+          )
         }
       })
       .catch(() => process.exit(1))
   }
 }
 
-module.exports = {
-  tauri
-}
+export default tauri
 
 // on test we use the module.exports
 if (process.env.NODE_ENV !== 'test') {

+ 22 - 19
tooling/cli.js/jest.config.js

@@ -1,4 +1,4 @@
-module.exports = {
+export default {
   globals: {
     __DEV__: true
   },
@@ -8,22 +8,24 @@ module.exports = {
   // cache: false,
   // verbose: true,
   // watch: true,
-  collectCoverage: true,
-  coverageDirectory: '<rootDir>/test/jest/coverage',
-  collectCoverageFrom: [
-    '<rootDir>/bin/**/*.js',
-    '<rootDir>/helpers/**/*.js',
-    '<rootDir>/api/**/*.js'
-  ],
-  coverageReporters: ['json-summary', 'text', 'lcov'],
-  coverageThreshold: {
-    global: {
-      //  branches: 50,
-      //  functions: 50,
-      //  lines: 50,
-      //  statements: 50
-    }
-  },
+
+  // TODO: coverage does not work with esm
+  // collectCoverage: true,
+  // coverageDirectory: '<rootDir>/test/jest/coverage',
+  // collectCoverageFrom: [
+  //   '<rootDir>/bin/**/*.js',
+  //   '<rootDir>/helpers/**/*.js',
+  //   '<rootDir>/api/**/*.js'
+  // ],
+  // coverageReporters: ['json-summary', 'text', 'lcov'],
+  // coverageThreshold: {
+  //   global: {
+  //  branches: 50,
+  //  functions: 50,
+  //  lines: 50,
+  //  statements: 50
+  //   }
+  // },
   testMatch: [
     '<rootDir>/test/jest/__tests__/**/*.spec.js',
     '<rootDir>/test/jest/__tests__/**/*.test.js'
@@ -37,11 +39,12 @@ module.exports = {
     '^api/(.*)$': '<rootDir>/src/api/$1',
     '^templates/(.*)$': '<rootDir>/src/templates/$1',
     '^test/(.*)$': '<rootDir>/test/$1',
-    '../../package.json': '<rootDir>/package.json'
+    '../../package.json': '<rootDir>/package.json',
+    'node:(.*)$': '$1'
   },
   transform: {
     '\\.toml$': 'jest-transform-toml',
     '\\.(js|ts)$': 'babel-jest'
   },
-  transformIgnorePatterns: ['node_modules/(?!(is-png|imagemin|p-pipe)/)']
+  extensionsToTreatAsEsm: ['.ts']
 }

+ 16 - 12
tooling/cli.js/package.json

@@ -2,6 +2,7 @@
   "name": "@tauri-apps/cli",
   "version": "1.0.0-beta.8",
   "description": "Command line interface for building Tauri apps",
+  "type": "module",
   "bin": {
     "tauri": "./bin/tauri.js"
   },
@@ -15,12 +16,12 @@
     "url": "https://opencollective.com/tauri"
   },
   "scripts": {
-    "build": "rimraf ./dist && webpack --progress",
-    "build-release": "rimraf ./dist && cross-env NODE_ENV=production webpack",
-    "test": "jest --runInBand --no-cache --testPathIgnorePatterns=\"(build|dev)\"",
+    "build": "rimraf ./dist && rollup -c --silent",
+    "build-release": "rimraf ./dist && cross-env NODE_ENV=production rollup -c",
+    "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --forceExit --no-cache --testPathIgnorePatterns=\"(build|dev)\"",
     "pretest": "yarn build",
     "prepublishOnly": "yarn build-release",
-    "test:local": "jest --runInBand",
+    "test:local": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --forceExit",
     "lint": "eslint --ext ts \"./src/**/*.ts\"",
     "lint-fix": "eslint --fix --ext ts \"./src/**/*.ts\"",
     "lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn",
@@ -43,7 +44,7 @@
     "access": "public"
   },
   "engines": {
-    "node": ">= 12.13.0",
+    "node": ">= 12.20.0",
     "npm": ">= 6.6.0",
     "yarn": ">= 1.19.1"
   },
@@ -72,6 +73,12 @@
     "@babel/core": "7.15.0",
     "@babel/preset-env": "7.15.0",
     "@babel/preset-typescript": "7.15.0",
+    "@jest/globals": "27.0.6",
+    "@rollup/plugin-babel": "5.3.0",
+    "@rollup/plugin-commonjs": "20.0.0",
+    "@rollup/plugin-node-resolve": "13.0.4",
+    "@rollup/plugin-replace": "^3.0.0",
+    "@rollup/plugin-typescript": "8.2.5",
     "@types/cross-spawn": "6.0.2",
     "@types/fs-extra": "9.0.12",
     "@types/global-agent": "2.1.1",
@@ -98,14 +105,11 @@
     "lockfile-lint": "4.6.2",
     "prettier": "2.3.2",
     "promise": "8.1.0",
-    "raw-loader": "4.0.2",
     "rimraf": "3.0.2",
-    "toml-loader": "1.0.0",
-    "ts-loader": "9.2.5",
-    "typescript": "4.3.5",
-    "webpack": "5.50.0",
-    "webpack-cli": "4.7.2",
-    "webpack-node-externals": "3.0.0"
+    "rollup": "2.56.2",
+    "rollup-plugin-terser": "7.0.2",
+    "tslib": "2.3.1",
+    "typescript": "4.3.5"
   },
   "resolutions": {
     "**/trim-newlines": "4.0.2"

+ 62 - 0
tooling/cli.js/rollup.config.js

@@ -0,0 +1,62 @@
+// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-License-Identifier: MIT
+
+// rollup.config.js
+import { readFileSync } from 'fs'
+import { terser } from 'rollup-plugin-terser'
+import resolve from '@rollup/plugin-node-resolve'
+import commonjs from '@rollup/plugin-commonjs'
+import babel from '@rollup/plugin-babel'
+import typescript from '@rollup/plugin-typescript'
+import pkg from './package.json'
+import replace from '@rollup/plugin-replace'
+import TOML from '@tauri-apps/toml'
+
+const cliManifestContents = readFileSync('../cli.rs/Cargo.toml').toString()
+const cliManifest = TOML.parse(cliManifestContents)
+
+export default {
+  input: {
+    'api/cli': './src/api/cli.ts',
+    'api/tauricon': './src/api/tauricon.ts',
+    'api/dependency-manager': './src/api/dependency-manager/index.ts',
+    'helpers/spawn': './src/helpers/spawn.ts',
+    'helpers/rust-cli': './src/helpers/rust-cli.ts',
+    'helpers/download-binary': './src/helpers/download-binary.ts'
+  },
+  treeshake: true,
+  perf: true,
+  output: {
+    dir: 'dist/',
+    entryFileNames: '[name].js',
+    format: 'esm',
+    exports: 'named',
+    globals: {}
+  },
+  plugins: [
+    replace({
+      __RUST_CLI_VERSION__: JSON.stringify(cliManifest.package.version),
+      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
+    }),
+    commonjs({}),
+    resolve({
+      // pass custom options to the resolve plugin
+      customResolveOptions: {
+        moduleDirectories: ['node_modules']
+      }
+    }),
+    typescript({
+      tsconfig: './tsconfig.json'
+    }),
+    babel({
+      configFile: false,
+      presets: [['@babel/preset-env'], ['@babel/preset-typescript']]
+    }),
+    terser()
+  ],
+  external: [
+    ...Object.keys(pkg.dependencies || {}),
+    ...Object.keys(pkg.peerDependencies || {})
+  ]
+}

+ 7 - 2
tooling/cli.js/src/api/dependency-manager/cargo-crates.ts

@@ -13,9 +13,12 @@ import { getCrateLatestVersion, semverLt } from './util'
 import logger from '../../helpers/logger'
 import { resolve as appResolve, tauriDir } from '../../helpers/app-paths'
 import { readFileSync, writeFileSync, existsSync } from 'fs'
-import toml from '@tauri-apps/toml'
 import inquirer from 'inquirer'
+import { createRequire } from 'module'
 
+const require = createRequire(import.meta.url)
+// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
+const toml = require('@tauri-apps/toml')
 const log = logger('dependency:crates')
 
 const dependencies = ['tauri']
@@ -23,7 +26,8 @@ const dependencies = ['tauri']
 function readToml<T>(tomlPath: string): T | null {
   if (existsSync(tomlPath)) {
     const manifest = readFileSync(tomlPath).toString()
-    return toml.parse(manifest) as any as T
+    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
+    return toml.parse(manifest) as T
   }
   return null
 }
@@ -124,6 +128,7 @@ async function manageDependencies(
   if (installedDeps.length || updatedDeps.length) {
     writeFileSync(
       appResolve.tauri('Cargo.toml'),
+      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
       toml.stringify(manifest as any)
     )
   }

+ 12 - 13
tooling/cli.js/src/api/dependency-manager/index.ts

@@ -9,17 +9,16 @@ import * as npmPackages from './npm-packages'
 
 const log = logger('dependency:manager')
 
-module.exports = {
-  async installDependencies() {
-    log('Installing missing dependencies...')
-    await rust.install()
-    await cargoCrates.install()
-    await npmPackages.install()
-  },
-  async updateDependencies() {
-    log('Updating dependencies...')
-    await rust.update()
-    await cargoCrates.update()
-    await npmPackages.update()
-  }
+export async function installDependencies(): Promise<void> {
+  log('Installing missing dependencies...')
+  await rust.install()
+  await cargoCrates.install()
+  await npmPackages.install()
+}
+
+export async function updateDependencies(): Promise<void> {
+  log('Updating dependencies...')
+  await rust.update()
+  await cargoCrates.update()
+  await npmPackages.update()
 }

+ 4 - 2
tooling/cli.js/src/api/dependency-manager/rust.ts

@@ -8,10 +8,12 @@ import getScriptVersion from '../../helpers/get-script-version'
 import { downloadRustup } from '../../helpers/download-binary'
 import logger from '../../helpers/logger'
 import { createWriteStream, unlinkSync, existsSync } from 'fs'
-import { resolve } from 'path'
+import { dirname, resolve } from 'path'
 import { platform } from 'os'
 import https from 'https'
+import { fileURLToPath } from 'url'
 
+const currentDirName = dirname(fileURLToPath(import.meta.url))
 const log = logger('dependency:rust')
 
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -36,7 +38,7 @@ async function download(url: string, dest: string): Promise<void> {
 async function installRustup(): Promise<void> {
   const assetName =
     platform() === 'win32' ? 'rustup-init.exe' : 'rustup-init.sh'
-  const rustupPath = resolve(__dirname, `../../bin/${assetName}`)
+  const rustupPath = resolve(currentDirName, `../../bin/${assetName}`)
   if (!existsSync(rustupPath)) {
     await downloadRustup()
   }

+ 12 - 11
tooling/cli.js/src/api/tauricon.ts

@@ -18,7 +18,7 @@
  * @license MIT
  */
 
-import { access, ensureDir, ensureFileSync, writeFileSync } from 'fs-extra'
+import * as fsExtra from 'fs-extra'
 import imagemin, { Plugin } from 'imagemin'
 import optipng from 'imagemin-optipng'
 import zopfli from 'imagemin-zopfli'
@@ -31,7 +31,14 @@ import { appDir, tauriDir } from '../helpers/app-paths'
 import logger from '../helpers/logger'
 import * as settings from '../helpers/tauricon.config'
 import chalk from 'chalk'
-import { version } from '../../package.json'
+import { createRequire } from 'module'
+
+// @ts-expect-error
+const { access, ensureDir, ensureFileSync, writeFileSync } = fsExtra.default
+
+const require = createRequire(import.meta.url)
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const { version } = require('../../package.json')
 
 const log = logger('app:spawn')
 const warn = logger('app:spawn', chalk.red)
@@ -200,7 +207,7 @@ const spinner = (): NodeJS.Timeout | null => {
   }, 500)
 }
 
-const tauricon = (exports.tauricon = {
+const tauricon = {
   validate: async function (src: string, target: string) {
     await validate(src, target)
     return typeof image === 'object'
@@ -512,12 +519,6 @@ const tauricon = (exports.tauricon = {
       throw err
     }
   }
-})
-/* eslint-enable @typescript-eslint/restrict-template-expressions */
-
-if (typeof exports !== 'undefined') {
-  if (typeof module !== 'undefined' && module.exports) {
-    exports = module.exports = tauricon
-  }
-  exports.tauricon = tauricon
 }
+
+export default tauricon

+ 2 - 4
tooling/cli.js/src/helpers/app-paths.ts

@@ -14,7 +14,7 @@ function resolvePath(basePath: string, dir: string): string {
 }
 
 const getAppDir = (): string => {
-  let dir = process.cwd()
+  let dir = process.env.__TAURI_TEST_APP_DIR ?? process.cwd()
   let count = 0
 
   // only go up three folders max
@@ -26,9 +26,7 @@ const getAppDir = (): string => {
     dir = normalize(join(dir, '..'))
   }
 
-  warn(
-    "Couldn't find recognize the current folder as a part of a Tauri project"
-  )
+  warn("Couldn't recognize the current folder as a part of a Tauri project")
   process.exit(1)
 }
 

+ 27 - 18
tooling/cli.js/src/helpers/download-binary.ts

@@ -1,15 +1,23 @@
-import stream from 'stream'
 import { promisify } from 'util'
+import stream from 'stream'
 import fs from 'fs'
-import got from 'got'
-import { CargoManifest } from '../types/cargo'
 import path from 'path'
 import { bootstrap } from 'global-agent'
-const pipeline = promisify(stream.pipeline)
+import { fileURLToPath } from 'url'
+import { createRequire } from 'module'
+
+// eslint-disable-next-line
+declare let __RUST_CLI_VERSION__: string
 
-// Webpack reads the file at build-time, so this becomes a static var
-// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
-const tauriCliManifest = require('../../../cli.rs/Cargo.toml') as CargoManifest
+const currentDirName = path.dirname(fileURLToPath(import.meta.url))
+
+const require = createRequire(import.meta.url)
+/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires */
+const got = require('got')
+/* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires */
+
+// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+const pipeline = promisify(stream.pipeline)
 
 const downloads: { [url: string]: boolean } = {}
 
@@ -44,13 +52,15 @@ async function downloadBinaryRelease(
 
   // TODO: Check hash of download
   // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, security/detect-non-literal-fs-filename
-  await pipeline(got.stream(url), fs.createWriteStream(outPath)).catch((e) => {
-    try {
-      // eslint-disable-next-line security/detect-non-literal-fs-filename
-      fs.unlinkSync(outPath)
-    } catch {}
-    throw e
-  })
+  await pipeline(got.stream(url), fs.createWriteStream(outPath)).catch(
+    (e: unknown) => {
+      try {
+        // eslint-disable-next-line security/detect-non-literal-fs-filename
+        fs.unlinkSync(outPath)
+      } catch {}
+      throw e
+    }
+  )
   // eslint-disable-next-line security/detect-object-injection
   downloads[url] = true
   // eslint-disable-next-line security/detect-non-literal-fs-filename
@@ -59,7 +69,6 @@ async function downloadBinaryRelease(
 }
 
 async function downloadCli(): Promise<void> {
-  const version = tauriCliManifest.package.version
   let platform: string = process.platform
   if (platform === 'win32') {
     platform = 'windows'
@@ -71,10 +80,10 @@ async function downloadCli(): Promise<void> {
     throw Error('Unsupported platform')
   }
   const extension = platform === 'windows' ? '.exe' : ''
-  const outPath = path.join(__dirname, `../../bin/tauri-cli${extension}`)
+  const outPath = path.join(currentDirName, `../../bin/tauri-cli${extension}`)
   console.log('Downloading Rust CLI...')
   await downloadBinaryRelease(
-    `tauri-cli-v${version}`,
+    `tauri-cli-v${__RUST_CLI_VERSION__}`,
     `tauri-cli_${platform}${extension}`,
     outPath
   )
@@ -87,7 +96,7 @@ async function downloadRustup(): Promise<void> {
   return await downloadBinaryRelease(
     'rustup',
     assetName,
-    path.join(__dirname, `../../bin/${assetName}`)
+    path.join(currentDirName, `../../bin/${assetName}`)
   )
 }
 

+ 8 - 11
tooling/cli.js/src/helpers/rust-cli.ts

@@ -3,24 +3,21 @@
 // SPDX-License-Identifier: MIT
 
 import { existsSync } from 'fs'
-import { resolve, join } from 'path'
+import { resolve, join, dirname } from 'path'
 import { spawnSync, spawn } from './spawn'
-import { CargoManifest } from '../types/cargo'
 import { downloadCli } from './download-binary'
+import { fileURLToPath } from 'url'
 
-const currentTauriCliVersion = (): string => {
-  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
-  const tauriCliManifest =
-    // eslint-disable-next-line @typescript-eslint/no-var-requires
-    require('../../../cli.rs/Cargo.toml') as CargoManifest
-  return tauriCliManifest.package.version
-}
+// eslint-disable-next-line
+declare let __RUST_CLI_VERSION__: string
+
+const currentDirName = dirname(fileURLToPath(import.meta.url))
 
 export async function runOnRustCli(
   command: string,
   args: string[]
 ): Promise<{ pid: number; promise: Promise<void> }> {
-  const targetPath = resolve(__dirname, '../..')
+  const targetPath = resolve(currentDirName, '../..')
   const targetCliPath = join(
     targetPath,
     'bin/tauri-cli' + (process.platform === 'win32' ? '.exe' : '')
@@ -80,7 +77,7 @@ export async function runOnRustCli(
           targetPath,
           'tauri-cli',
           '--version',
-          currentTauriCliVersion()
+          __RUST_CLI_VERSION__
         ],
         process.cwd()
       )

+ 6 - 6
tooling/cli.js/test/jest/__tests__/build.spec.js

@@ -1,13 +1,13 @@
-const path = require('path')
-const fixtureSetup = require('../fixtures/app-test-setup')
+import path from 'path'
+import * as fixtureSetup from '../fixtures/app-test-setup.js'
+import { spawn } from 'helpers/spawn'
+
 const appDir = path.join(fixtureSetup.fixtureDir, 'app')
 const distDir = path.join(appDir, 'dist')
 
-const spawn = require('helpers/spawn').spawn
-
 function runBuildTest(args) {
   fixtureSetup.initJest('app')
-  const { build } = require('dist/api/cli')
+  console.log(2)
   return new Promise(async (resolve, reject) => {
     try {
       let success = false
@@ -20,7 +20,7 @@ function runBuildTest(args) {
         setTimeout(resolve, 2000)
       })
       process.chdir(appDir)
-      console.log(server)
+      const { build } = await import('dist/api/cli')
       const { promise } = await build(args)
       await promise
 

+ 6 - 6
tooling/cli.js/test/jest/__tests__/dev.spec.js

@@ -1,10 +1,11 @@
-const path = require('path')
-const fixtureSetup = require('../fixtures/app-test-setup')
+import path from 'path'
+import isRunning from 'is-running'
+import http from 'http'
+import { statSync, createReadStream } from 'fs'
+import * as fixtureSetup from '../fixtures/app-test-setup.js'
 const distDir = path.resolve(fixtureSetup.fixtureDir, 'app', 'dist')
 
 function startDevServer() {
-  const http = require('http')
-  const { statSync, createReadStream } = require('fs')
   const app = http.createServer((req, res) => {
     if (req.method === 'GET') {
       if (req.url === '/') {
@@ -30,13 +31,12 @@ function startDevServer() {
 
 function runDevTest(tauriConfig) {
   fixtureSetup.initJest('app')
-  const { dev } = require('dist/api/cli')
   return new Promise(async (resolve, reject) => {
     try {
       process.chdir(path.join(fixtureSetup.fixtureDir, 'app'))
+      const { dev } = await import('dist/api/cli')
       const { promise, pid } = await dev({ config: tauriConfig })
 
-      const isRunning = require('is-running')
       let success = false
       const checkIntervalId = setInterval(async () => {
         if (!isRunning(pid) && !success) {

+ 6 - 2
tooling/cli.js/test/jest/__tests__/tauri.spec.js

@@ -1,4 +1,9 @@
-const { tauri } = require('bin/tauri')
+import { jest } from '@jest/globals'
+import tauri from 'bin/tauri'
+import { createRequire } from 'module'
+const require = createRequire(import.meta.url)
+
+const { version } = require('../../../package.json')
 
 describe('[CLI] cli.js', () => {
   it('displays a help message', async () => {
@@ -29,7 +34,6 @@ describe('[CLI] cli.js', () => {
   it('gets you version', async () => {
     jest.spyOn(console, 'log')
     const tests = ['--version', '-v']
-    const version = require('../../../package.json').version
     for (const test of tests) {
       tauri([test])
       expect(console.log.mock.calls[0][0]).toBe(version)

+ 6 - 41
tooling/cli.js/test/jest/__tests__/tauricon.spec.js

@@ -1,54 +1,17 @@
-const appTestSetup = require('../fixtures/app-test-setup')
+import * as appTestSetup from '../fixtures/app-test-setup.js'
 appTestSetup.initJest('app')
 
-const tauricon = require('api/tauricon')
-
 describe('[CLI] tauri-icon internals', () => {
-  it('tells you the version', () => {
+  it('tells you the version', async () => {
+    const tauricon = (await import('api/tauricon')).default
     const version = tauricon.version()
     expect(!!version).toBe(true)
   })
-
-  it('will not validate a non-file', async () => {
-    jest.spyOn(process, 'exit').mockImplementation(() => true)
-    await tauricon.validate(
-      'test/jest/fixtures/doesnotexist.png',
-      'test/jest/fixtures/'
-    )
-    expect(process.exit.mock.calls[0][0]).toBe(1)
-    jest.clearAllMocks()
-  })
-  it('will not validate a non-png', async () => {
-    jest.spyOn(process, 'exit').mockImplementation(() => true)
-    await tauricon.validate(
-      'test/jest/fixtures/notAMeme.jpg',
-      'test/jest/fixtures/'
-    )
-    expect(process.exit.mock.calls[0][0]).toBe(1)
-    jest.clearAllMocks()
-  })
-
-  it('should fail if PNG does not have transparency', async () => {
-    jest.spyOn(process, 'exit').mockImplementation(() => true)
-    await tauricon.validate(
-      'test/jest/fixtures/no-alpha.png',
-      'test/jest/fixtures/'
-    )
-    expect(process.exit.mock.calls[0][0]).toBe(1)
-    jest.clearAllMocks()
-  })
-
-  it('can validate an image as PNG', async () => {
-    const valid = await tauricon.validate(
-      'test/jest/fixtures/tauri-logo.png',
-      'test/jest/fixtures/'
-    )
-    expect(valid).toBe(true)
-  })
 })
 
 describe('[CLI] tauri-icon builder', () => {
   it('will still use default compression if missing compression chosen', async () => {
+    const tauricon = (await import('api/tauricon')).default
     const valid = await tauricon.make(
       'test/jest/fixtures/tauri-logo.png',
       'test/jest/tmp/missing',
@@ -59,6 +22,7 @@ describe('[CLI] tauri-icon builder', () => {
 
   it('will not validate a non-file', async () => {
     try {
+      const tauricon = (await import('api/tauricon')).default
       await tauricon.make(
         'test/jest/fixtures/tauri-foo-not-found.png',
         'test/jest/tmp/optipng',
@@ -70,6 +34,7 @@ describe('[CLI] tauri-icon builder', () => {
   })
 
   it('makes a set of icons with optipng', async () => {
+    const tauricon = (await import('api/tauricon')).default
     const valid = await tauricon.make(
       'test/jest/fixtures/tauri-logo.png',
       'test/jest/tmp/optipng',

+ 9 - 6
tooling/cli.js/test/jest/__tests__/template.spec.js

@@ -1,22 +1,25 @@
-const fixtureSetup = require('../fixtures/app-test-setup')
-const { resolve } = require('path')
-const { writeFileSync, readFileSync } = require('fs')
+import * as fixtureSetup from '../fixtures/app-test-setup.js'
+import { resolve, dirname } from 'path'
+import { writeFileSync, readFileSync } from 'fs'
+import { init, build } from 'dist/api/cli'
+import { fileURLToPath } from 'url'
+
+const currentDirName = dirname(fileURLToPath(import.meta.url))
 
 describe('[CLI] cli.js template', () => {
   it('init a project and builds it', async () => {
     const cwd = process.cwd()
-    const fixturePath = resolve(__dirname, '../fixtures/empty')
+    const fixturePath = resolve(currentDirName, '../fixtures/empty')
     const tauriFixturePath = resolve(fixturePath, 'src-tauri')
 
     fixtureSetup.initJest('empty')
 
     process.chdir(fixturePath)
 
-    const { init, build } = require('dist/api/cli')
     const { promise } = await init({
       directory: process.cwd(),
       force: true,
-      tauriPath: resolve(__dirname, '../../../../..'),
+      tauriPath: resolve(currentDirName, '../../../../..'),
       ci: true
     })
     await promise

+ 11 - 34
tooling/cli.js/test/jest/fixtures/app-test-setup.js

@@ -1,44 +1,21 @@
-const path = require('path')
-const process = require('process')
+import { jest } from '@jest/globals'
+import path from 'path'
+import http from 'http'
+import { fileURLToPath } from 'url'
 
-const mockFixtureDir = path.resolve(__dirname, '../fixtures')
+const currentDirName = path.dirname(fileURLToPath(import.meta.url))
+const mockFixtureDir = path.resolve(currentDirName, '../fixtures')
 
-module.exports.fixtureDir = mockFixtureDir
+export const fixtureDir = mockFixtureDir
 
-function mockResolvePath(basePath, dir) {
-  return dir && path.isAbsolute(dir) ? dir : path.resolve(basePath, dir)
-}
-
-module.exports.initJest = (mockFixture) => {
+export const initJest = (mockFixture) => {
   jest.setTimeout(1200000)
-  jest.mock('helpers/non-webpack-require', () => {
-    return (path) => {
-      const value = require('fs').readFileSync(path).toString()
-      if (path.endsWith('.json')) {
-        return JSON.parse(value)
-      }
-      return value
-    }
-  })
 
-  jest.mock('helpers/app-paths', () => {
-    const path = require('path')
-    const appDir = path.join(mockFixtureDir, mockFixture)
-    const tauriDir = path.join(appDir, 'src-tauri')
-    return {
-      appDir,
-      tauriDir,
-      resolve: {
-        app: (dir) => mockResolvePath(appDir, dir),
-        tauri: (dir) => mockResolvePath(tauriDir, dir)
-      }
-    }
-  })
+  const mockAppDir = path.join(mockFixtureDir, mockFixture)
+  process.env.__TAURI_TEST_APP_DIR = mockAppDir
 }
 
-module.exports.startServer = (onSuccess) => {
-  const http = require('http')
-
+export const startServer = (onSuccess) => {
   const responses = {
     writeFile: null,
     readFile: null,

+ 1 - 1
tooling/cli.js/test/jest/fixtures/app/src-tauri/Cargo.toml

@@ -26,7 +26,7 @@ tauri-build = { path = "../../../../../../../core/tauri-build" }
 serde_json = "1.0.66"
 serde = "1.0"
 serde_derive = "1.0"
-tauri = { path = "../../../../../../../core/tauri", features =["api-all"]}
+tauri = { path = "../../../../../../../core/tauri", features = ["api-all"] }
 
 [features]
 default = [ "custom-protocol" ]

+ 2 - 2
tooling/cli.js/test/jest/jest.setup.js

@@ -1,6 +1,6 @@
-jest.setTimeout(1200000)
+import { jest } from '@jest/globals'
 
-global.Promise = require('promise')
+jest.setTimeout(1200000)
 
 setTimeout(() => {
   // do nothing

+ 1 - 1
tooling/cli.js/tsconfig.json

@@ -2,7 +2,7 @@
   "compilerOptions": {
     "outDir": "./dist/",
     "strict": true,
-    "module": "commonjs",
+    "module": "es2020",
     "target": "es5",
     "allowJs": true,
     "esModuleInterop": true,

+ 0 - 49
tooling/cli.js/webpack.config.js

@@ -1,49 +0,0 @@
-const path = require('path')
-const nodeExternals = require('webpack-node-externals')
-
-module.exports = {
-  entry: {
-    'api/cli': './src/api/cli.ts',
-    'api/tauricon': './src/api/tauricon.ts',
-    'api/dependency-manager': './src/api/dependency-manager/index.ts',
-    'helpers/spawn': './src/helpers/spawn.ts',
-    'helpers/rust-cli': './src/helpers/rust-cli.ts',
-    'helpers/download-binary': './src/helpers/download-binary.ts'
-  },
-  mode: process.env.NODE_ENV || 'development',
-  devtool: 'source-map',
-  module: {
-    rules: [
-      {
-        test: /\.tsx?$/,
-        use: 'ts-loader',
-        exclude: /node_modules/
-      },
-      {
-        test: /(templates|api)[\\/].+\.js/,
-        use: 'raw-loader'
-      },
-      {
-        test: /\.toml?$/,
-        use: 'toml-loader'
-      }
-    ]
-  },
-  node: false,
-  resolve: {
-    extensions: ['.ts', '.js']
-  },
-  output: {
-    library: 'tauri',
-    libraryTarget: 'umd',
-    filename: '[name].js',
-    path: path.resolve(__dirname, 'dist'),
-    globalObject: 'this'
-  },
-  externals: [
-    nodeExternals({
-      allowlist: ['imagemin', 'is-png', 'p-pipe', 'file-type']
-    })
-  ],
-  externalsPresets: { node: true }
-}

File diff suppressed because it is too large
+ 164 - 474
tooling/cli.js/yarn.lock


Some files were not shown because too many files changed in this diff