让 Webpack 不捆绑文件

Posted

技术标签:

【中文标题】让 Webpack 不捆绑文件【英文标题】:Get Webpack not to bundle files 【发布时间】:2017-02-27 00:46:45 【问题描述】:

所以现在我正在使用一个原型,我们正在使用 webpack(用于构建 .tsx 文件和复制 .html 文件)和 webpack-dev-server 之间的组合用于开发服务。你可以假设我们也使用 React 和 ReactDOM 作为两个库依赖项。我们当前的构建输出是以下结构:

dist
    -favicon.ico
    -index.html
    -main.js
    -main.js.map // for source-mapping between tsx / js files

这会将所有模块(包括库依赖项放入大捆绑文件中)。我希望最终结果如下所示:

dist
    -favicon.ico
    -index.html
    -appName.js
    -appName.min.js
    -react.js
    -react.min.js
    -reactDOM.js
    -reactDOM.min.js

我在 index.html 和 .tsx 文件中的 import 语句中引用了每个库。所以我的问题是这个... 如何从 webpack 生成这个巨大的捆绑 .js 文件到单个 .js 文件(包括库,无需单独指定每个文件)? **奖励:我知道如何做 prod/dev 环境标志,那么我如何缩小这些单独的文件(同样不捆绑它们)?

当前 webpack.config:

var webpack = require("webpack"); // Assigning node package of webpack dependency to var for later utilization
var path = require("path"); // // Assigning node package of path dependency to var for later utilization

module.exports = 
    entry:  [
                "./wwwroot/app/appName.tsx", // Starting point of linking/compiling Typescript and dependencies, will need to add separate entry points in case of not deving SPA
                "./wwwroot/index.html", // Starting point of including HTML and dependencies, will need to add separate entry points in case of not deving SPA
                "./wwwroot/favicon.ico" // Input location for favicon
            ],
    output: 
        path: "./dist/", // Where we want to host files in local file directory structure
        publicPath: "/", // Where we want files to appear in hosting (eventual resolution to: https://localhost:4444/)
        filename: "appName.js" // What we want end compiled app JS file to be called
    ,

    // Enable sourcemaps for debugging webpack's output.
    devtool: "source-map",

    devServer: 
        contentBase: './dist', // Copy and serve files from dist folder
        port: 4444, // Host on localhost port 4444
        // https: true, // Enable self-signed https/ssl cert debugging
        colors: true // Enable color-coding for debugging (VS Code does not currently emit colors, so none will be present there)
    ,

    resolve: 
        // Add '.ts' and '.tsx' as resolvable extensions.
        extensions: [
            "",
            ".ico",
            ".js",
            ".ts",
            ".tsx",
            ".web.js",
            ".webpack.js"
        ]
    ,

    module: 
        loaders: [
            // This loader copies the index.html file & favicon.ico to the output directory.
            
                test: /\.(html|ico)$/,
                loader: 'file?name=[name].[ext]'
            ,
            // All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
            
                test: /\.tsx?$/,
                loaders: ["ts-loader"]
            
        ],

        preLoaders: [
            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            
                test: /\.js$/,
                loader: "source-map-loader"
            
        ]
    ,

    // When importing a module whose path matches one of the following, just
    // assume a corresponding global variable exists and use that instead.
    // This is important because it allows us to avoid bundling all of our
    // dependencies, which allows browsers to cache those libraries between builds.
    // externals: 
    //     "react": "React",
    //     "react-dom": "ReactDOM",
    //     "redux": "Redux"
    // 
;

【问题讨论】:

Webpack 的唯一目的是做捆绑;你确定你不想要任何捆绑,或者你只是想要一些东西捆绑而其他东西不?如果是后一种选择,您可以了解为什么需要单独指定每个文件。 所以我喜欢使用 webpack 将 Typescript 转换为 javascript 的事实。我知道我们仍然需要一个构建系统,但不想仅仅依赖 gulp 或(就像很多人习惯使用的那样)grunt。我也不知道使用 npm 脚本之类的东西是否会提供足够的功能,除非那里的单个包可以满足相同的需求。鉴于这些情况,您能否提供进一步的建议? 我过去已经发现webpack允许基于通用模块进行分块......如果有人可以根据上述提供更多信息,那也可以解决我的问题。谢谢! 就我个人而言,我认为 webpack 只是一个很好的打包构建工具,如果你不想打包,我会坚持使用 gulp 或 NPM 脚本。 @Jacob Webpack 的亮点还在于它允许您需要非 JS 文件。如果你正在尝试构建一个同构的应用程序,你必须在客户端和服务器上都使用 webpack。但是,服务器实际上并没有从捆绑中受益。 【参考方案1】:

output 设置更改为名称驱动,例如

    entry: 
        dash: 'app/dash.ts',
        home: 'app/home.ts',
    ,
    output: 
        path: './public',
        filename: 'build/[name].js',
        sourceMapFilename: 'build/[name].js.map'
    ,

【讨论】:

经过一些研究后最接近最终解决方案的结果。我在上面的解释中添加了我最终解决方案的评论。使用您的方法的一个缺点是,当指定不同类型的文件作为文件加载器的入口点(即 favicon.ico、index.html)时,它们也将与 .js 以及它们的原始文件一起输出。跨度> 知道这在项目中节省了多少时间吗?如果 webpack 基本上只是将文件从输入复制到输出,那么在添加转译和其他插件/加载器转换之前是否有很多开销?【参考方案2】:

要扩展@basarat 的答案,您可以使用节点标准库中的glob 包来构建“入口”配置:

const glob = require("glob");

module.exports = [
  
    target: "node",
    entry: glob.sync("./src/**/*.test.ts,tsx").reduce((acc, file) => 
      acc[file.replace(/^\.\/src\//, "")] = file;
      return acc;
    , ),
    output: 
      filename: "[name].js",
      chunkFilename: "[name]-[id].js",
      path: __dirname + "/dist"
    ,
    //...
  
];

这会构建与其源名称相同的文件,将.ts.tsx 替换为.js

【讨论】:

【参考方案3】:

从问题中复制的 OP 答案

最终找到了适合我需求的解决方案,尽管再次以 webpack-y 方式,需要一些额外的配置。仍然想让它更有活力,但会在稍后的时间点完善它。我正在寻找的解决方案是“分块”公共模块的能力,但我将其声明为给定 webpack 中提供的“入口”点的文件名。我不介意一些文件被合并,这是有意义的,但考虑到项目不是 SPA(单页应用程序),我希望整个文件处于组件级别。

附加代码最终是:

plugins: [
    new webpack.optimize.CommonsChunkPlugin( // This plugin is for extracting and created "chunks" (extracted parts of the code that are common and aren't page specific)
        // One of these instances of plugins needs to be specified for EACH chunk file output desired
        filename: "common.js", // Filename for this particular set of chunks to be stored
        name: "common", // Entry point name given for where to pull all of the chunks
        minChunks: 3 // Minimum number of chunks to be created
    )
]

我还必须通过变量名参数化入口点(例如见下文),以便我可以将 react、react-dom 和 redux 模块分配给 common.js 文件。

entry:  
    main:    "./wwwroot/app/appName.tsx", // Starting point of linking/compiling Typescript and dependencies, will need to add separate entry points in case of not deving SPA
    index:   "./wwwroot/index.html", // Starting point of including HTML and dependencies, will need to add separate entry points in case of not deving SPA
    favicon: "./wwwroot/favicon.ico", // Input location for favicon
    common:  [ "react", "react-dom", "redux" ] // All of the "chunks" to extract and place in common file for faster loading of common libraries between pages
,

【讨论】:

您是否估计过不捆绑节省的时间(在分析时间中?)与捆绑相比?

以上是关于让 Webpack 不捆绑文件的主要内容,如果未能解决你的问题,请参考以下文章

无法让 webpack require.ensure 分块方法与 react-router 一起使用并生成单独的捆绑文件

webpack - 在不捆绑的情况下编译 1 个 ts 文件(2 个条目)

webpack 不再缩小捆绑包

webpack 可以在不需要或导入的情况下捆绑 js 文件吗? Q2:为啥需要图表?

对 jsx 文件反应 js webpack 捆绑错误

Webpack:如何使用动态捆绑组合两个完全独立的捆绑包