Uncaught Error: Cannot find module in Browserify Gulp when transpiled

Uncaught Error: Cannot find module in Browserify Gulp when transpiled

我一直在拼命地尝试解决由于我的 JS 中与 Browserify 捆绑在一起的依赖项而导致的极其缓慢的构建。为此,我提出了一些我的 gulp 文件调用的实用方法,如下所示...

const paths = require("./paths.gulpfile")
const gulp = require("gulp")
const uglify = require("gulp-uglify")
const sourcemaps = require("gulp-sourcemaps")
const browserify = require("browserify")
const shim = require("browserify-shim")
const watchify = require("watchify")
const babelify = require("babelify")
const source = require("vinyl-source-stream")
const buffer = require("vinyl-buffer")
const gutil = require("gulp-util")
const babel = require("gulp-babel")

const externalLibs = [
    "jquery", 
    "react",
    "react-dom",    
    "prop-types",
    "bootstrap-sass" 
]
const ignoredLibs = []
const vendorLibs = [
    "google-maps",
    "history", "history/createBrowserHistory",
    "lodash", "lodash/debounce",
    "path-to-regexp"
]

/**
 * JS related gulp tasks
 * 
 * @returns {object} utility functions for JS based gulp tasks.
 */
module.exports = function(compiledName) {

    /**
     * Bundle definition for dev.
     * 
     * @param {object} bundler 
     * @returns A bundle.
     */
    const appBundle = function(bundler) {
        return bundler.bundle()
            .pipe(source(compiledName + ".js"))
            .pipe(buffer())
            .pipe(sourcemaps.init({ loadMaps: true }))
            .pipe(babel())
            .pipe(sourcemaps.write("./"))
            .pipe(gulp.dest(paths.scriptsBuildPath))
    }

    /**
     * Bundle definition for production.
     * 
     * @param {object} bundler 
     * @returns A bundle.
     */
    const appMinBundle = function(bundler) {
        return bundler.bundle()
            .pipe(source(compiledName + ".min.js"))
            .pipe(buffer())
            .pipe(sourcemaps.init({ loadMaps: true }))
            .pipe(babel())
            .pipe(uglify({
                compress: true,
                mangle: {
                    except: [
                        "$",
                        "createBrowserHistory", 
                        "debounce",
                        "GoogleMapsLoader", 
                        "history", 
                        "jQuery",
                        "lodash",
                        "PropTypes",
                        "React", 
                        "ReactDom",
                        "toRegex"
                    ]
                }
            }))
                .on("error", gutil.log)
            .pipe(sourcemaps.write("./"))
            .pipe(gulp.dest(paths.scriptsBuildPath))
    }

    /**
     * Bundle definition for vendors.
     * 
     * @param {object} bundler The browserify instance
     * @param {string} env The environment
     * @returns A bundle.
     */
    const vendorsBundle = function(bundler, env) {
        // eslint-disable-next-line
        process.env.NODE_ENV = env ? env : process.env.NODE_ENV
        return bundler.bundle()
            .pipe(source("vendors.js"))
            .pipe(buffer())
            .pipe(sourcemaps.init({ loadMaps: true }))
            .pipe(sourcemaps.write("./"))
            .pipe(gulp.dest(paths.scriptsBuildPath))
    }

    /**
     * Minified Bundle definition for vendors.
     * 
     * @param {object} bundler The browserify instance
     * @param {string} env The environment
     * @returns A bundle.
     */
    const vendorsMinBundle = function(bundler, env) {
        // eslint-disable-next-line
        process.env.NODE_ENV = env ? env : process.env.NODE_ENV
        return bundler
            .transform("uglifyify", { global: true })
            .bundle()
            .pipe(source("vendors.min.js"))
            .pipe(buffer())
            .pipe(sourcemaps.init({ loadMaps: true }))
            .pipe(uglify({
                compress: true,
                mangle: true
            }))
            .pipe(sourcemaps.write("./"))
            .pipe(gulp.dest(paths.scriptsBuildPath))
    }

    /**
     * Builds the JavaScript bundles.
     * 
     * @param {bool} debugMode 
     * @param {bool} watch 
     * @param {func} bundleCallback 
     * @returns A bundle.
     */
    const buildJs = function(debugMode, watch, bundleCallback) {
        const entryPoint = paths.scriptsSrcPath + "app.js"

        let bundler = browserify({
            entries: [entryPoint],
            transform: [[babelify, { "presets": ["react", "es2015", "stage-0"] }], shim],
            debug: debugMode,
            cache: {}, packageCache: {}, fullPaths: true
        })

        bundler.external(externalLibs)
        bundler.external(vendorLibs)

        ignoredLibs.forEach(function(lib) {
            bundler.ignore(require.resolve(lib, { expose: lib }))
        })

        if (watch) {
            bundler = watchify(bundler)

            bundler.on("update", function() {
                bundleCallback(bundler)
            })

            bundler.on("log", function(msg) {
                gutil.log(msg)
            })
        }

        return bundleCallback(bundler)
    }

    /**
     * Builds the JavaScript vendor bundle.
     * 
     * @param {string} env The environment
     * @returns A bundle.
     */
    const buildVendorJs = function(env) {

        const bundler = browserify({
            debug: true
        })

        //bundler.external(externalLibs)

        vendorLibs.forEach(function(lib) {
            bundler.require(lib)
        })

        const bigBundle = vendorsBundle(bundler, env)
        return env == "production" ? vendorsMinBundle(bundler, env) : bigBundle
    }

    return {
        buildJs : buildJs,
        buildVendorJs: buildVendorJs,
        appBundle: appBundle,
        appMinBundle: appMinBundle
    }
}

externalLibs 应该是 CDN 加载的并且被完全排除,vendorLibs 将被一起放入一个缩小的文件中,appBundle 是不言自明的。

在引入一个单独的 vendor.js 文件之前,我已经完成了这项工作,并且我在那里拥有所有依赖项,但我一直在让 React 在缩小时玩球时遇到问题,最终放弃并返回到CDN(甚至不准备再去那里——浪费了太多的日子)。

这让我剩下的供应商,但我现在遇到一个问题,即找不到 PropTypes....

_prelude.js:1 未捕获错误:找不到模块 'prop-types' 在 s (_prelude.js:1)

当 prop-types 是 vendor.js 包的一部分时,尝试访问 React 时出现了类似的错误 - 我不知道接下来要尝试什么。

我发现解决方案是我没有将新的外部组件添加到 package.json 中的 bowserify shim 配置...

  "browserify-shim": {
    "./node_modules/jquery/dist/jquery.js": "$",
    "react": "global:React",
    "react-dom": "global:ReactDOM",
    "prop-types": "global:PropTypes"