如何 select node_modules dist flavor 与 webpack 捆绑

How to select node_modules dist flavor to bundled with webpack

问题:

在我将 AJV.js 升级到版本 6.4 之后,我的供应商捆绑包包括 "uri-js" ESNEXT 版本而不是破坏 IE11 兼容性的 ES5 版本。

分析:

我认为 AJV 通过 require('uri-js') 调用引用 uri-js,而 uri-js 有两种形式:

/node_modules/uri-js/dist/:

出于某种原因,Webpack (V 4.8) 将 'esnext' 风格的 uri-js 捆绑到我的供应商捆绑包中,而不是使用 'es5'。我找不到 how/where 我必须指定我的首选构建目标是。

这是我的 webpack.config.js:

const path = require("path");
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    entry: {
        app: './src/index.tsx'
    },
    output: {
        filename: "js/[name].bundle.js",
        path: __dirname + "/dist"
    },
    devtool: "source-map",
    resolve: {
        extensions: [".ts", ".tsx", ".js", ".jsx", ".json"]
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: "ts-loader"
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    use: [{
                        loader: "css-loader",
                        options: {
                            localIdentName: '[local]--[hash:5]',
                            sourceMap: true
                        }

                    }, {
                        loader: "less-loader",
                        options: {
                            sourceMap: true
                        }
                    }],
                    fallback: "style-loader",
                    publicPath: "../"
                }),
                exclude: "/node_modules/"
            },
            {
                test: /\.html$/,
                use: 'raw-loader'
            },
            {
                test: /\.jpe?g$|\.gif$|\.png$/i,
                loader: "file-loader?name=assets/img/[name].[ext]"
            },
            {
                test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
                use: "file-loader?name=assets/[name].[ext]"
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
            filename: "quino/style/style.css",
            allChunks: true
        }),
        new HtmlWebpackPlugin({
            template: "src/index.html",
            filename: "index.html"
        }),
        new CopyWebpackPlugin([])
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: { test: /[\/]node_modules[\/]/, name: "vendors", chunks: "all" }
            }
        }
    }
};

package.json:

{
  "name": "MyApp",
  "version": "1.0.0",
  "sideEffects": false,
  "description": "-",
  "private": false,
  "scripts": {
    "build": "webpack --config webpack.config.js --mode production",
    "dev": "webpack-dev-server --config webpack.config.js --host 0.0.0.0 --progress --colors --history-api-fallback --mode development"
  },
  "author": "Me",
  "license": "some",
  "devDependencies": {
   .... stuff ....
  },
  "dependencies": {
    .... stuff ....
    "ajv": "^6.4.0",
    .... more stuff ....
  }
}

我知道我自己的代码会使用 TypeScript (V 2.8) 编译器转译为 ES5。但是 node_modules 呢?尤其是已经在其 dist 文件夹中发布 ES5 版本的那个?

万一这很重要我的 tsconfig.json:

{
  "compilerOptions": {
    "outDir": "build/dist",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom"],
    "sourceMap": true,
    "allowJs": true,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDir": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "exclude": [
    "dist/**",
    "./*.js",
    "node_modules",
    "build",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts"
  ]
}

我还考虑过包括 Babel 以将所有 node_modules 降级到 ES5,但这对我来说听起来有点矫枉过正,尤其是因为模块已经包含了 ES5 风格。

问题:

  1. 我可以为我的 node_modules 指定我更喜欢 dist 文件夹的 ES5 版本吗?也许在我的 webpack.config 或 package.json?

  2. 如何选择正确的 node_modules/.../dist/ 文件夹?

  1. Can I specify that I prefere ES5 version of the dist folder for my node_modules? Maybe in my webpack.config or in package.json?

据我所知,没有通用的方法来处理同一 NPM 包的不同风格(例如 ES5、ESNEXT 等)。每个包都有自己的做事方式。所以没有通用的选择方法。相反,必须将内容合并到您的任务运行程序(Gulp、Webpack、Grunt 等)中以解决出现的问题。

  1. How does the selection of the right node_modules/.../dist/ folders work?

一个 NPM 包包含一个 package.json。在这个文件中有一个 main 字段,它指定在你的应用程序中要 include/use 的内容或捆绑程序选择的内容等。如果不存在 main 值,将使用 index.js作为默认值。

选择过程的其余部分是特定于包的。这也适用于包的文件夹结构。有些使用 /dist/.. 来表示不同的风格,有些则在其他文件夹中提供调试和生产版本。高度依赖于每个包本身使用了 files/versions 个文件。

没有像 .net 中那样的标准化系统 Nuget 打包 lib/... 文件夹的结构。

我仍然不确定的是为什么选择 URL-JS 的 ESNEXT 版本,因为 URL-JS 指向它的 ES5 版本。致力于此 ;-)