簡體   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