|
| 1 | +/** |
| 2 | + * This script is used to re-export packages that Cypress publishes on its own. |
| 3 | + * It is executed individually in a postbuild step by individual npm/* packages. |
| 4 | + * For example, usually, Cypress will publish the `npm/react` directory as a `@cypress/react` package. |
| 5 | + * However, the Cypress binary will also ship an export for `cypress/react` that's guaranteed to work |
| 6 | + * with this version of the binary |
| 7 | + */ |
| 8 | +const shell = require('shelljs') |
| 9 | +const path = require('path') |
| 10 | +const packlist = require('npm-packlist') |
| 11 | +const fs = require('fs') |
| 12 | + |
| 13 | +shell.set('-v') // verbose |
| 14 | +shell.set('-e') // any error is fatal |
| 15 | + |
| 16 | +// This script will be run in a postbuild task for each npm package |
| 17 | +// that will be re-exported by Cypress |
| 18 | +const currentPackageDir = process.cwd() |
| 19 | + |
| 20 | +// 1. We'll run npm's own "packlist" against the npm package to be published (@cypress/react, etc) |
| 21 | +// to make sure we don't miss any files when we copy them over to the CLI package |
| 22 | +// The files that will be returned here are the ones from @cypress/react's package.json['files'] key. |
| 23 | +packlist({ path: currentPackageDir }) |
| 24 | +.then((files) => { |
| 25 | + // 2. Move all of the files that would be published under @cypress/react |
| 26 | + // to be copied under cli/react (drop the @cypress namespace) |
| 27 | + const cliPath = path.join(__dirname, '..', 'cli') |
| 28 | + |
| 29 | + // Typically, these packages are independently published as @cypress/package-name |
| 30 | + // e.g. @cypress/vue => import whatever from 'cypress/vue' |
| 31 | + // The files will wind up at cypress/cli/vue/* |
| 32 | + const currentPackageConfig = require(path.join(process.cwd(), 'package.json')) |
| 33 | + const exportName = currentPackageConfig.name.replace('@cypress/', '') |
| 34 | + const outDir = path.join(cliPath, exportName) |
| 35 | + |
| 36 | + // 3. For each file, mkdir if not exists, and then copy the dist'd assets over |
| 37 | + // Shell is synchronous by default, but we don't actually need to await for the results |
| 38 | + // to write to the `cliPackageConfig` at the end |
| 39 | + files.forEach((f) => { |
| 40 | + // mkdir if not exists |
| 41 | + const { dir } = path.parse(f) |
| 42 | + |
| 43 | + if (dir) { |
| 44 | + shell.mkdir('-p', path.join(outDir, dir)) |
| 45 | + } |
| 46 | + |
| 47 | + shell.cp(path.join(currentPackageDir, f), path.join(outDir, f)) |
| 48 | + }) |
| 49 | + |
| 50 | + // After everything is copied, let's update the Cypress cli package.json['exports'] map. |
| 51 | + const isModule = currentPackageConfig.type === 'module' |
| 52 | + |
| 53 | + const cliPackageConfig = require(path.join(cliPath, 'package.json')) |
| 54 | + |
| 55 | + const subPackageExports = cliPackageConfig.exports[`./${exportName}`] = {} |
| 56 | + const esmEntry = isModule ? currentPackageConfig.main : currentPackageConfig.module |
| 57 | + |
| 58 | + if (esmEntry) { |
| 59 | + // ./react/dist/cypress-react-esm.js, etc |
| 60 | + subPackageExports.import = `./${exportName}/${esmEntry}` |
| 61 | + } |
| 62 | + |
| 63 | + if (!isModule) { |
| 64 | + // ./react/dist/cypress-react-cjs.js, etc |
| 65 | + subPackageExports.require = `./${exportName}/${currentPackageConfig.main}` |
| 66 | + } |
| 67 | + |
| 68 | + if (!cliPackageConfig.files.includes(exportName)) { |
| 69 | + cliPackageConfig.files.push(exportName) |
| 70 | + } |
| 71 | + |
| 72 | + const output = `${JSON.stringify(cliPackageConfig, null, 2) }\n` |
| 73 | + |
| 74 | + // eslint-disable-next-line no-console |
| 75 | + console.log('Writing to CLI package.json for', exportName) |
| 76 | + |
| 77 | + fs.writeFileSync(path.join(cliPath, 'package.json'), output, 'utf-8') |
| 78 | +}) |
0 commit comments