[英]Merging requirejs and plain js file together
I'm developping a small website, and the main HTML page basically looks like this:我正在开发一个小网站,主要的 HTML 页面基本上是这样的:
<html lang="en">
<head>
<script src="ace.js" type="text/javascript"><script>
<script src="ext-language_tools.js" type="textjavascript"></script>
<script src="mode-mongo.js" type="text/javascript"></script>
<script src="playground.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function() {
ace.config.setModuleUrl("ace/mode/mongo", "mode-mongo.js")
configEditor = ace.edit(document.getElementById("editor"), {
"mode": "ace/mode/mongo",
"useWorker": false
})
}
</script>
</head>
<body>
<div class="editor">
</body>
</html>
( real one is visible here ). (真正的在这里可见)。
Here are the unminified files:以下是未缩小的文件:
The first 3 js files use requirejs , the 4th is just plain js前 3 个 js 文件使用requirejs ,第 4 个只是普通的 js
Is there a way to merge those 4 files into a single file in order to have something like this in my HTML instead ?有没有办法将这 4 个文件合并到一个文件中,以便在我的 HTML 中使用类似的内容?
<html lang="en">
<head>
<script src="bundle.js" type="text/javascript"><script>
<script type="text/javascript">
window.onload = function() {
configEditor = ace.edit(document.getElementById("editor"), {
"mode": "ace/mode/mongo",
"useWorker": false
})
}
</script>
</head>
<body>
<div class="editor">
</body>
</html>
My goal is to load all this js code at once in a single HTTP request我的目标是在单个 HTTP 请求中一次加载所有这些 js 代码
You can require
them in one js file and reference that in your template.您可以在一个 js 文件中
require
它们并在您的模板中引用它。
Something like this:像这样的东西:
bundle.js:捆绑.js:
require(../ace.js);
// other files
require(../playground.js);
I am a bit confused.我有点困惑。 You say you are using requirejs for the first 3 files, but this is not my understanding of how requirejs is used.
你说你在前 3 个文件中使用了requirejs ,但这不是我对requirejs是如何使用的理解。 You would normally have a main JavaScript file (let's call it main.js ) and your HTML would load a single JavaScript file, ie the require.js file, which would specify the main.js file to be loaded:
您通常会有一个主要的 JavaScript 文件(我们称之为main.js )并且您的 HTML 将加载一个 JavaScript 文件,即require.js文件,该文件将指定要加载的main.js文件:
<html lang="en">
<head>
<script src="require.js" data-main="main"><script>
<!-- The following does not currently use require.js: -->
<script src="playground.js"><script>
<script>
window.onload = function() {
configEditor = ace.edit(document.getElementById("editor"), {
"mode": "ace/mode/mongo",
"useWorker": false
})
}
</script>
</head>
<body>
<div class="editor">
</body>
</html>
And then inside of main.js , you would use require()
(or requirejs()
) to load any other scripts you need to run.然后在main.js内部,您将使用
require()
(或requirejs()
)加载您需要运行的任何其他脚本。 For example:例如:
require(["ace"], function(ace) {
//This function is called when scripts/ace.js is loaded.
//If ace.js calls define(), then this function is not fired until
//ace's dependencies have loaded, and the ace argument will hold
//the module value for "ace".
});
And the window.onload
event handler, which requires the ace module, would be moved to inside main.js file.需要ace模块的
window.onload
事件处理程序将被移动到main.js文件中。
Now if you want to bundle the 4 files into a single file, then assuming you have Node.js
installed the easiest way to proceed is to first install requirejs using npm:现在,如果您想将这 4 个文件捆绑到一个文件中,那么假设您安装了
Node.js
,最简单的方法是首先使用 npm 安装requirejs :
npm install -g requirejs
Next install uglify :接下来安装uglify :
npm install uglify-js -g
Then create a new JavaScript file main.js in the directory that has your scripts:然后在包含您的脚本的目录中创建一个新的 JavaScript 文件main.js :
require(['ace', 'ext-language-tools', 'mode-mongo', 'playground'], function(ace) {
window.onload = function() {
configEditor = ace.edit(document.getElementById("editor"), {
"mode": "ace/mode/mongo",
"useWorker": false
});
};
});
Then execute from the scripts directory:然后从脚本目录执行:
r.js -o name=main out=bundle.js
If you are running under Windows, you will need to replace r.js
above with r.js.cmd
.如果您在Windows下运行,则需要更换
r.js
以上r.js.cmd
。 This should give you a single, minified file bundle.js .这应该会给你一个单一的、缩小的文件bundle.js 。 If you don't want the file minified then:
如果您不想缩小文件,则:
r.js -o name=main out=bundle.js optimize=none
Then modify your HTML to look something like:然后将您的 HTML 修改为如下所示:
<html lang="en">
<head>
<script src="require.js" data-main="bundle"><script>
</head>
<body>
<div class="editor">
</body>
</html>
Of course, you do not need the window.onload
event in your main.js
:当然,您不需要
main.js
的window.onload
事件:
require(['ace', 'ext-language-tools', 'mode-mongo', 'playground'], function() {});
And then your HTML becomes:然后你的 HTML 变成:
<html lang="en">
<head>
<script src="require.js" data-main="bundle"><script>
<script>
require(['ace'], function(ace) {
window.onload = function() {
configEditor = ace.edit(document.getElementById("editor"), {
"mode": "ace/mode/mongo",
"useWorker": false
});
};
});
</script>
</head>
<body>
<div class="editor">
</body>
</html>
@Booboo's answer is mostly correct. @Booboo 的回答大部分是正确的。 But I'd like to add my 5 cents:
但我想加上我的 5 美分:
ace.js
in your repo, and in your question is already bundled! ace.js
在您的 repo 中,并且在您的问题中已经捆绑! It doesn't actually use the requirejs
.requirejs
。 Everything is already inside.requirejs
s docs and the @Booboo's answer.requirejs
的文档和@Booboo 的回答所建议的设置。requirejs
's bundle mechanism you'll need to add the sources of the ace
.requirejs
的捆绑机制,您需要添加ace
的来源。r.js
.r.js
。 It's not clear what is your goal.<script src="require.js" data-main="main" />
will be enough.<script src="require.js" data-main="main" />
就足够了。ace
project. ace
项目中只有 2 个附加文件。 Others are yours, so bundle only them.ace.js
, then every time your code changes your users will have to download all the KB's of ace.js
again and again, because browser won't be able to use a cached version of it.ace.js
的代码捆绑ace.js
,那么每次您的代码更改时,您的用户都必须一次又一次地下载ace.js
所有知识库,因为浏览器将无法使用它的缓存版本. And the main idea of the bundles (and also one of the reasons behind CDN) is exactly about minimizing the number of requests in the long run .This is an interesting question, since there are a bunch of potential solutions that span a few eras and philosophies in JavaScript and Web development.这是一个有趣的问题,因为在 JavaScript 和 Web 开发中,有许多跨越几个时代和哲学的潜在解决方案。 I'll talk about about the easiest and oldest, file concatenation, and briefly touch upon RequireJS, and more modern approaches of using dedicated web bundlers.
我将讨论最简单和最古老的文件连接,并简要介绍 RequireJS,以及使用专用 Web 捆绑器的更现代方法。 There's also the unstated, underlying assumption of why you feel you need to bundle it-- there might be some assumptions of file loading which might not be true, particularly with HTTP/2.
还有一个未说明的潜在假设,即为什么您觉得需要捆绑它——可能有一些文件加载假设可能不正确,尤其是对于 HTTP/2。
If you want something quick, easy, and old school, you can just combine (concatenate) all of your JavaScript files together.如果您想要快速、简单和老派的东西,您可以将所有 JavaScript 文件组合(连接)在一起。 That's essentially what's happening in your initial web page: the browser downloads all of the JavaScript files and runs them in order.
这基本上就是您的初始网页中发生的事情:浏览器下载所有 JavaScript 文件并按顺序运行它们。
To concatenate using Unix/Linux/OS X:要使用 Unix/Linux/OS X 进行连接:
cat path/to/ace.js <(echo) \
path/to/ext-language_tools.js <(echo) \
path/to/mode-mongo.js <(echo) \
path/to/playground.js \
> path/to/bundle.js
(You can combine them all on one line if you remove the \\
s. You can also omit the <(echo)
if you know the file ends with a new line) (如果删除
\\
s,则可以将它们全部合并在一行中。如果您知道文件以新行结尾,也可以省略<(echo)
)
It bears mentioning the RequireJS way of doing things, that uses require
statements, since that's the philosophy that ace.js is developed under.值得一提的是 RequireJS 的做事方式,它使用
require
语句,因为这是 ace.js 的开发理念。 Using this philosophy, files are intended to stay separated as modules and are loaded as needed.使用这种理念,文件旨在作为模块保持分离并根据需要加载。 Other answers explain this approach in more detail, though I'll add that bundling doesn't seem to be the idiomatic way to use RequireJS-- the library originally intended (though doesn't require) modules to be split into different files.
其他答案更详细地解释了这种方法,但我会补充说,捆绑似乎不是使用 RequireJS 的惯用方式——库最初打算(尽管不需要)将模块拆分为不同的文件。
In recent years, people have adopted web bundlers-- like webpack, parcel, rollup, and more -- to manage multiple files and dependencies.近年来,人们采用了 web 打包器(如 webpack、parcel、rollup 等)来管理多个文件和依赖项。 These tools are intended to output a single web bundle and have a lot of nice, customizable features for that.
这些工具旨在输出单个 Web 包,并为此提供许多不错的、可定制的功能。 They might need a bit of work to get up and running, and need to use a CommonJS plugin to get
require
working.他们可能需要做一些工作才能启动和运行,并且需要使用 CommonJS 插件来让
require
工作。 For instance, see here to get ace working with webpack.例如,请参阅此处让 ace 与 webpack 一起工作。
Depending on your concerns and situation, bundling might not need be an optimization you need.根据您的顾虑和情况,捆绑可能不需要是您需要的优化。 Historically, bundling was used as a way to minimize network requests, since the number of network connections was limited, and sometimes files requested other files, leading to loading in serial.
历史上,捆绑被用作最小化网络请求的一种方式,因为网络连接的数量是有限的,有时文件会请求其他文件,导致串行加载。 Many of these concerns were addressed with HTTP/2.
HTTP/2 解决了其中的许多问题。 Just make sure that your web server supports HTTP/2 and that you're serving all the files on that server.
只需确保您的 Web 服务器支持 HTTP/2 并且您正在为该服务器上的所有文件提供服务。 For more information about this, see this question .
有关这方面的更多信息,请参阅此问题。 You probably care most of how it operates in practice, so you'd probably want to benchmark it either way, but you might not be gaining much.
您可能最关心它在实践中的运作方式,因此您可能希望以任何一种方式对其进行基准测试,但您可能不会获得太多收益。
We can simply use webpack to get what you're looking for我们可以简单地使用 webpack 来获取您正在寻找的内容
webpack with vanilla 带有香草的 webpack
module.exports = {
entry: ["./ace.js", "./playground.js" ....],
output: {
filename: "bundle.js"
}
}
You can use require
and source script
together,你可以一起使用
require
和source script
,
At the first , config your webpack.config.js
Webpack Docs首先,配置你的
webpack.config.js
Webpack Docs
const path = require('path');
const toml = require('toml');
const yaml = require('yamljs');
const json5 = require('json5');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
stats: 'errors-only',
mode: 'development',
entry: './src/index.js',
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 3000,
},
plugins: [
new HtmlWebpackPlugin({
title: 'Artificial Intelligence',
}),
],
output: {
filename: '[contenthash].bundle.js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
{
test: /\.toml$/i,
type: 'json',
parser: {
parse: toml.parse,
},
},
{
test: /\.yaml$/i,
type: 'json',
parser: {
parse: yaml.parse,
},
},
{
test: /\.json5$/i,
type: 'json',
parser: {
parse: json5.parse,
},
},
],
},
};
In the second step, require
the files you need第二步,
require
你需要的文件
// Es5
const x = require('x');
const y = require('y');
// Es6
import * as x from 'x';
import y from 'y';
import { z } from 'z';
Use the script tag
instead of importing
使用
script tag
而不是importing
<html lang="en">
<head>
...
</head>
<body>
<script src="x.js"></script>
<script src="y.js"></script>
<script>
const x = new X();
</script>
</body>
</html>
Notice: Scripts must be executed after all注意:脚本终究要执行
You can also use the scripts
you imported in the script tag
in your files您还可以
use the scripts
您在文件imported in the script tag
中imported in the script tag
App.js应用程序.js
const x = new X();
cosnt y = new Y();
List the files you do not require as follows列出你不需要的文件如下
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.