繁体   English   中英

将 requirejs 和普通 js 文件合并在一起

[英]Merging requirejs and plain js file together

我正在开发一个小网站,主要的 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>

(真正的在这里可见)。

以下是未缩小的文件:

前 3 个 js 文件使用requirejs ,第 4 个只是普通的 js

有没有办法将这 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>

编辑

我的目标是在单个 HTTP 请求中一次加载所有这些 js 代码

您可以在一个 js 文件中require它们并在您的模板中引用它。

像这样的东西:

捆绑.js:

require(../ace.js);
// other files
require(../playground.js);

我有点困惑。 你说你在前 3 个文件中使用了requirejs ,但这不是我对requirejs是如何使用的理解。 您通常会有一个主要的 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>

然后在main.js内部,您将使用require() (或requirejs() )加载您需要运行的任何其他脚本。 例如:

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".
});

需要ace模块的window.onload事件处理程序将被移动到main.js文件中。

现在,如果您想将这 4 个文件捆绑到一个文件中,那么假设您安装了Node.js ,最简单的方法是首先使用 npm 安装requirejs

npm install -g requirejs

接下来安装uglify

npm install uglify-js -g

然后在包含您的脚本的目录中创建一个新的 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
        });
    };
});    

然后从脚本目录执行:

r.js -o name=main out=bundle.js

如果您在Windows下运行,则需要更换r.js以上r.js.cmd 这应该会给你一个单一的、缩小的文件bundle.js 如果您不想缩小文件,则:

r.js -o name=main out=bundle.js optimize=none

然后将您的 HTML 修改为如下所示:

<html lang="en">
  <head>
    <script src="require.js" data-main="bundle"><script>
  </head>
  <body>
    <div class="editor">
  </body>
</html>

当然,您不需要main.jswindow.onload事件:

require(['ace', 'ext-language-tools', 'mode-mongo', 'playground'], function() {});

然后你的 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 的回答大部分是正确的。 但我想加上我的 5 美分:

  1. ace.js在您的 repo 中,并且在您的问题中已经捆绑! 它实际上并不使用requirejs 一切都已经在里面了。 您可以在DevTools 中自行查看:只有一个网络请求。 因此,它不适用于requirejs的文档和@Booboo 的回答所建议的设置。
  2. 为了能够使用requirejs的捆绑机制,您需要添加ace的来源。
  3. 你也可以,但你不必使用r.js 不清楚你的目标是什么。 但是,如果出于某种原因,您只想在 html 中使用单个脚本入口点(不知道为什么需要这个) - <script src="require.js" data-main="main" />就足够了。
  4. 再说一次,由于您的目标不明确,让我建议 - 不要这样做。 ace项目中只有 2 个附加文件。 其他人是你的,所以只捆绑他们。 如果您将ace.js的代码捆绑ace.js ,那么每次您的代码更改时,您的用户都必须一次又一次地下载ace.js所有知识库,因为浏览器将无法使用它的缓存版本. 捆绑包的主要思想(也是 CDN 背后的原因之一)正是关于从长远来看最大限度地减少请求数量。 如果您担心新用户不会再次访问,因为您的网站在他们第一次访问时需要更长的时间来初始化...好吧,也许速度不是您主要关心的问题。 此外,浏览器可能有 6 个并行连接,因此一个捆绑包实际上会降低您的网站速度。

这是一个有趣的问题,因为在 JavaScript 和 Web 开发中,有许多跨越几个时代和哲学的潜在解决方案。 我将讨论最简单和最古老的文件连接,并简要介绍 RequireJS,以及使用专用 Web 捆绑器的更现代方法。 还有一个未说明的潜在假设,即为什么您觉得需要捆绑它——可能有一些文件加载​​假设可能不正确,尤其是对于 HTTP/2。

快捷方式

如果您想要快速、简单和老派的东西,您可以将所有 JavaScript 文件组合(连接)在一起。 这基本上就是您的初始网页中发生的事情:浏览器下载所有 JavaScript 文件并按顺序运行它们。

要使用 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

(如果删除\\ s,则可以将它们全部合并在一行中。如果您知道文件以新行结尾,也可以省略<(echo)

RequireJS 方式

值得一提的是 RequireJS 的做事方式,它使用require语句,因为这是 ace.js 的开发理念。 使用这种理念,文件旨在作为模块保持分离并根据需要加载。 其他答案更详细地解释了这种方法,但我会补充说,捆绑似乎不是使用 RequireJS 的惯用方式——库最初打算(尽管不需要)将模块拆分为不同的文件。

Web Bundler 方式

近年来,人们采用了 web 打包器(如 webpack、parcel、rollup 等)来管理多个文件和依赖项。 这些工具旨在输出单个 Web 包,并为此提供许多不错的、可定制的功能。 他们可能需要做一些工作才能启动和运行,并且需要使用 CommonJS 插件来让require工作。 例如,请参阅此处让 ace 与 webpack 一起工作。

需要捆绑吗?

根据您的顾虑和情况,捆绑可能不需要是您需要的优化。 历史上,捆绑被用作最小化网络请求的一种方式,因为网络连接的数量是有限的,有时文件会请求其他文件,导致串行加载。 HTTP/2 解决了其中的许多问题。 只需确保您的 Web 服务器支持 HTTP/2 并且您正在为该服务器上的所有文件提供服务。 有关这方面的更多信息,请参阅此问题 您可能最关心它在实践中的运作方式,因此您可能希望以任何一种方式对其进行基准测试,但您可能不会获得太多收益。

我们可以简单地使用 webpack 来获取您正在寻找的内容

带有香草的 webpack

module.exports = {
  entry: ["./ace.js", "./playground.js" ....],
  output: {
    filename: "bundle.js"
  }
}

你可以一起使用requiresource script

首先,配置你的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,
                },
            },
        ],
    },
};

第二步, require你需要的文件

// Es5
const x = require('x');
const y = require('y');

// Es6
import * as x from 'x';
import y from 'y';
import { z } from 'z';

使用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>

注意:脚本终究要执行

您还可以use the scripts您在文件imported in the script tagimported in the script tag

应用程序.js

const x = new X();
cosnt y = new Y();

列出你不需要的文件如下

暂无
暂无

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

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