让Webpack不打包文件

52

目前我正在使用原型,其中我们使用了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的唯一目的是打包;您确定不需要任何打包,还是只想打包某些文件而不打包其他文件?如果是后者,您可以理解为什么需要逐个指定每个文件。 - Jacob
1
所以我喜欢可以使用Webpack将TypeScript编译成JavaScript。我知道我们仍需要一个构建系统,但不想仅仅依赖于gulp或(像很多人过去使用的)grunt。除非某些单独的npm软件包可以满足相同的需求,否则我也不知道使用类似npm脚本的东西是否能提供足够的功能。考虑到这些条件,您能否提供进一步的建议? - B. Blunt
我之前已经发现webpack可以基于共同模块进行分块。如果有人能够根据上述提供更多信息,那也可以解决我的问题。谢谢! - B. Blunt
3
我个人认为webpack只是一个用于打包的很好的构建工具,如果你不需要打包,我建议你使用gulp或NPM脚本。 - Jacob
5
@Jacob Webpack的另一个优点是可以引入非JS文件。如果你想构建一个同构应用程序,必须在客户端和服务器端都使用Webpack。然而,服务器并不会从打包中获益。 - mpen
我已经将你在问题中的回答复制到了一个实际的答案中。如果你更喜欢自己回答,请@我,我会删除下面的wiki。 - Liam
3个回答

31

output设置更改为基于名称的驱动,例如:

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

1
在一些研究后,最终解决方案最接近的是我在上面的说明中添加了我的最终解决方案的注释。使用您的方法的一个缺点是,当将不同类型的文件(如favicon.ico、index.html)指定为file-loader的入口点时,它们也将与其原始文件一起输出为.js文件。 - B. Blunt
这在项目中能节省多少时间?如果Webpack只是从输入复制文件到输出,那么有多少开销 - 在添加转译和其他插件/加载器转换之前? - Jason Kleban

15
为了进一步解释@basarat的答案,您可以使用来自Node标准库的glob包来构建“entry”配置:

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


实际上这对于获取文件并编译为TSC非常有帮助。但是我遇到了一个缩小错误Uncaught Error: Minified React error #321; 访问https://reactjs.org/docs/error-decoder.html?invariant=321以获取完整消息,或使用非缩小的dev环境以获取完整错误和其他有用的警告。 - jasmo2
实际上,这对于获取文件并编译为TSC非常有帮助。但是我遇到了一个压缩错误Uncaught Error: Minified React error #321; visit https://reactjs.org/docs/error-decoder.html?invariant=321 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. - undefined

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
},

你有没有估计过不打包与打包相比节省了多少时间(在分析时间方面)? - Jason Kleban

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接