mokkabonna / inquirer-autocomplete-prompt

Autocomplete prompt for inquirer
ISC License
350 stars 82 forks source link

Dynamic Import Not Working in Webpack Project #158

Closed anran758 closed 6 months ago

anran758 commented 7 months ago

Hi, I've encountered some issues while using inquirer-autocomplete-standalone.

My Node.js project is built with Webpack and TypeScript. When using Webpack, setting the target to 'node' automatically converts import syntax to require syntax. I've also looked at the examples provided, but due to Webpack, dynamic imports don't seem to work either.

Currently, my project already depends on @inquirer/prompts, and it would be redundant to downgrade and install inquirer and inquirer-autocomplete-prompt again. How can I use inquirer-autocomplete-standalone with Webpack packaging?

webpack.config.js

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const nodeExternals = require('webpack-node-externals');

const webpackConf = {
  mode: 'production',
  entry: {
    index: path.resolve(__dirname, 'src/index.ts'),
  },
  output: {
    path: path.resolve(__dirname, 'lib'),
    filename: 'index.js',
    clean: true,
  },
  target: 'node',
  cache: { type: 'filesystem' },
  module: {
    rules: [
      {
        test: /\.(js|ts)$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  externalsPresets: {
    node: true,
  },
  externals: [
    nodeExternals(),
    nodeExternals({
      modulesDir: path.resolve(__dirname, '../../node_modules'),
    }),
    { deasync: 'commonjs deasync' },
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
    },
    extensions: ['.ts', '.js'],
    fallback: { path: false },
  },
  optimization: {
    minimizer: [
      new TerserPlugin({
        extractComments: false,
      }),
    ],
  },
};

module.exports = webpackConf;

tsconfig.json

{
  "compilerOptions": {
    "allowJs": true,

    // Code generation settings
    "target": "es2015",

    // Module resolution and path settings
    "rootDir": ".",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "resolveJsonModule": true,
    "module": "ESNext",
    "moduleResolution": "node",

    // Strictness and type checking
    "strict": true,
    "noImplicitAny": false,
    "skipLibCheck": true,
    "types": ["minapp-sdk-typings"],

    // Interoperability with the ES6 module system
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,

    // Miscellaneous settings
    "composite": false
  },
  "include": ["src", "typings", "./package.json"],
  "exclude": ["node_modules", "lib", "__tests__"]
}

package.json

{
  "name": "@mincloudx/cli",
  "version": "0.2.1",
  "description": "A command-line tool based on the MinCloud ecosystem, designed to offer a simple and quick way to help developers efficiently manage MinCloud-related tasks.",
  "author": "anran758 <anran758@gmail.com>",
  "homepage": "https://github.com/anran758/mincloudx/tree/main/packages/cli#readme",
  "license": "MIT",
  "main": "lib/index.js",
  "type": "commonjs",
  "publishConfig": {
    "access": "public"
  },
  "keywords": [
    "mincloudx",
    "typescript",
    "faas",
    "cli"
  ],
  "repository": {
    "type": "git",
    "url": "git+https://github.com/anran758/mincloudx.git",
    "directory": "packages/cli"
  },
  "scripts": {
    "prepublishOnly": "pnpm run build",
    "build": "webpack --node-env=production",
    "watch": "webpack --watch",
    "test": "mincloudx"
  },
  "bin": {
    "mincloudx": "./bin/cli.js"
  },
  "files": [
    "bin",
    "lib",
    "LICENSE",
    "README.md"
  ],
  "bugs": {
    "url": "https://github.com/anran758/mincloudx/issues"
  },
  "peerDependencies": {
    "minapp-sdk-typings": "^3.1.0"
  },
  "devDependencies": {
    "@types/ini": "^1.3.31",
    "@types/lodash": "^4.14.202",
    "@types/mkdirp": "^1.0.2",
    "@types/osenv": "^0.1.1",
    "@types/rc": "^1.2.1",
    "@types/tough-cookie": "^4.0.2",
    "minapp-sdk-typings": "^3.1.0",
    "terser-webpack-plugin": "^5.3.10",
    "ts-loader": "^9.5.1",
    "typescript": "^4.7.2",
    "webpack-cli": "^5.1.4",
    "webpack-node-externals": "^3.0.0"
  },
  "dependencies": {
    "@inquirer/prompts": "^4.1.0",
    "axios": "^1.3.4",
    "axios-cookiejar-support": "^4.0.6",
    "chalk": "^4.1.2",
    "commander": "^9.4.1",
    "form-data": "^4.0.0",
    "import-fresh": "^3.3.0",
    "ini": "^3.0.1",
    "inquirer-autocomplete-prompt": "^2.0.0",
    "inquirer-autocomplete-standalone": "^0.8.1",
    "lodash": "^4.17.21",
    "mkdirp": "^1.0.4",
    "npmlog": "^7.0.1",
    "osenv": "^0.1.5",
    "rc": "^1.2.8",
    "tough-cookie": "^4.1.2",
    "webpack": "^5.90.3",
    "webpack-merge": "^5.10.0"
  }
}
anran758 commented 7 months ago

I understood why the CommonJS example in import-esm-in-typescript-examples works correctly, as the tsconfig.json is set to transform CommonJS syntax into ESModule syntax.

While attempting to address the import issue, I also came across other developers facing similar challenges in the issues section of inquirer.js. Is there a suitable solution available?

anran758 commented 7 months ago

I got it. The issue was due to my use of nodeExternals, which by default marks inquirer-autocomplete-standalone as external, leading to the compiled code being converted to require when executed by node.

nodeExternals({ allowlist: ['inquirer-autocomplete-standalone'] }),

However, when I excluded inquirer-autocomplete-standalone from nodeExternals, it started working properly. The downside is that the size of the dist increases (since it bundles the third-party library together), and I'm not sure if this is the expected behavior for packaging a CLI.

anran758 commented 6 months ago

now Inquirer#1267 support it.