简体   繁体   English

将文件合并到Webpack的条目中

[英]Merge files into entry for Webpack

Background: 背景:

I have been tasked with transitioning a JS library that uses multiple build tools into one that only uses Webpack where ultimately we will refactor the code to use es6 classes. 我的任务是将使用多个构建工具的JS库转换为仅使用Webpack的JS库,最终我们将重构代码以使用es6类。

Currently the library is over 10 years old is consists of multiple concatenated files which can interact / depend on each other (spaghetti code galore!). 目前,该库已有10多年的历史了,它由多个可以相互影响/相互依赖的串联文件组成(意大利面条代码非常丰富!)。 When combined all the chunks become one IIFE file which adds specific calls to the window object. 合并后,所有块均成为一个IIFE文件,该文件将特定的调用添加到窗口对象。

As it stands we have Grunt concatenating all the files together and then we run it through uglify. 就目前而言,我们有Grunt将所有文件串联在一起,然后通过uglify运行它。

The only way I have "sort" off managed to replicate what we are doing with Grunt is by using script-loader. 我设法“分类”以复制我们用Grunt做的唯一方法是使用脚本加载器。

The problem with script-loader is that it exposes everything globally and as the library I am working on contains multiple chunks which can depend on each other, this will not suffice. 脚本加载程序的问题在于它会全局公开所有内容,并且由于我正在使用的库包含多个可以相互依赖的块,因此这是不够的。

Question: 题:

Is there a way in webpack where I can concatenate multiple files (chunks) into one? 在webpack中,有没有一种方法可以将多个文件(块)串联在一起?

For example: 例如:

  • chunkA.js chunkA.js

     var varFromChunkA = "hello"; function methodFromA(){} 
  • chunkB.js chunkB.js

     console.log(varFromChunkA); methodFromB(); 
  • entry.js entry.js

     console.log(varFromChunkA + ' World'); methodFromA(); methodFromB(); 

Ultimately I would like the output from entry.js to have access to variables / methods from chunkA and B etc without having modules being required. 最终,我希望entry.js的输出可以访问chunkA和B等中的变量/方法,而无需模块。 (The entire library is split into code based namespaces, no modules at all). (整个库分为基于代码的名称空间,根本没有模块)。

So combining the chunks above I would want webpack to output something like: 因此,结合上面的块,我希望webpack输出类似:

var varFromChunkA = "hello";
function methodFromA(){}

console.log(varFromChunkA);
methodFromB();

/***Webpack Code***/
//Entry.js file
//I can access the objects / methods defined above
console.log(varFromChunkA +' World from inside entry.js');
/*** End of Webpack Code **/

And in the browser console when the js is loaded I would expect: 在浏览器控制台中,加载js时,我期望:

Hello

Hello World

Hello World from inside entry.js

Is this possible? 这可能吗?

Essentially I would like the output from Webpack to include some pure JS which will be accessible by any JS file generated by weback... 本质上,我希望Webpack的输出包含一些纯JS,weback生成的任何JS文件都可以访问...

Tried using script-loader and concat plugins but had no luck. 尝试使用脚本加载器和concat插件,但没有运气。

Im using Webpack 4 我正在使用Webpack 4

The way I have resolved it so far is by using script loader for parts of the file that need to be exposed Globally. 到目前为止,我解决该问题的方法是使用脚本加载程序来处理需要全局公开的文件部分。 The rest I am using a node script to concat them all together. 其余的我使用节点脚本将它们连接在一起。

The combination of all files are then passed on to webpack. 然后将所有文件的组合传递到webpack。

Would love to do all this with just webpack but I think this is a happy compromise and means I can get rid off grunt. 很乐意仅使用webpack来完成所有这些工作,但是我认为这是一个令人愉快的妥协,意味着我可以摆脱烦恼。

webpack normally works in conjunction with a module importing system like es6 modules, amd or commonjs. webpack通常与模块导入系统(例如es6模块,amd或commonjs)结合使用。

The thing you intend to do is another approach and not what webpack was meant to do. 您打算做的事情是另一种方法,而不是webpack的意图。

So if you want to refactor the code to use es6 classes anyway, I would recommend to introduce the es6 module system as well! 因此,如果您仍然想重构代码以使用es6类,我建议您也介绍es6模块系统!

This way you can use webpack naturally the way it was intended. 这样,您可以自然地使用webpack。

More information: http://exploringjs.com/es6/ch_modules.html#sec_basics-of-es6-modules 详细信息: http : //exploringjs.com/es6/ch_modules.html#sec_basics-of-es6-modules

UPDATE: If you would like to concatenate the files after the webpack processing with other files, just do that with a script! 更新:如果您想在webpack处理后将文件与其他文件连接起来,只需使用脚本即可! You could use javascript or even bash ( cat chunkA.js chunkB.js entry.js > bundled.js ) 您可以使用javascript甚至bash( cat chunkA.js chunkB.js entry.js > bundled.js

You could even add this bash code into the scripts section of your package.json like this: 您甚至可以将以下bash代码添加到package.json的scripts部分中,如下所示:

"bundle": "cat chunkA.js chunkB.js entry.js > bundled.js"

and run it with npm run bundle 并使用npm run bundle运行它

It's been a while, but if it helps. 已经有一段时间了,但是如果有帮助的话。
Following @Bynho's idea, I found a solution by using a script node " concat " associated directly in the configuration with a promise... 遵循@Bynho的想法,我通过使用直接在配置中与promise关联的脚本节点“ concat ”找到了一个解决方案...
I use here 3 config files as suggested in doc to adapt to your needs. 我在这里按照文档中的建议使用3个配置文件来适应您的需求。
I find this practice useful because it allows to automate it without having to too work on this, after all. 我发现这种做法很有用,因为毕竟它可以使它自动化而不必为此做太多工作。

(webpack 4.) (Webpack4。)
In the file "webpack.common.js" 在文件“ webpack.common.js”中

module.exports = {
    entry: {
        app: './src/concatened.js',
    },
... config
}

In the file "webpack.dev.js" 在文件“ webpack.dev.js”中

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const concat = require('concat');

const result = concat(['./src/utils.js', './src/index.js'],
        './src/concatened.js')
    .then(result => merge(common, {
        mode: 'development',
        ... config
    }));

module.exports = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result);
            reject((err) => console.log(err));
        }, 10);
    });
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM