node.js - 使用 Laravel Mix 合并多个文件

标签 node.js laravel gulp laravel-elixir laravel-mix

我目前正在深入研究 Laravel Mix,到目前为止,虽然我完全了​​解 Laravel Mix 是什么以及它是如何工作的,但我正在尝试更多地了解常见做法和“操作方法”。 ..

例如,考虑这个文件结构:

/resources/assets/js/app.js (all global functions)
/resources/assets/js/index/index.js (functions specific to index.js)
/resources/assets/js/about/about.js (functions specific to about.js)
/resources/assets/js/contact/contact.js (functions specific to contact.js)

现在,理想情况下,我希望通过以下方式组合和缩小以下内容:

/public/js/index/index-some_hash.js (including app.js)
/public/js/about/about-some_hash.js (including app.js)
/public/js/contact/contact-some_hash.js (including app.js)

据我了解,实现这一点的方法如下:

// Index
mix.js([
    'resources/assets/js/app.js',
    'resources/assets/js/index/index.js'
], 'public/js/index/index.js').version();

// About
mix.js([
    'resources/assets/js/app.js',
    'resources/assets/js/about/about.js'
], 'public/js/about/about.js').version();

// Contact
mix.js([
    'resources/assets/js/app.js',
    'resources/assets/js/contact/contact.js'
], 'public/js/contact/contact.js').version();

我的问题

很简单,我想知道以上是否是做我想做的事情的正确方法?有没有更好的方法或更常见的方法来实现这一点?

如果上述结构错误,并且我的文件还有其他组合方式,请分享您的知识。但是,除非有很好的理由,否则我想避免以下情况:

  • 为每个页面提供两个单独的文件,即 app.min.js 和 index.min.js。 这需要每页两次查找,理想情况下应该尽可能少
  • 为我网站上的所有页面提供相同的文件。 将代码提供给不打算使用它的页面是一种资源浪费,无论缓存如何......

一个想法...

我注意到其中一个 JS 文件中有一行代码; require('./bootstrap');.称我为老式的,但我从未在 JavaScript 中看到过这种情况(我假设它来自 node.js)。也就是说,显然它只是将 bootstrap.js 文件作为依赖项加载到特定文件中。因此,考虑到这一点,以下解决方案会更好:

about.js

require('./app'); // Include global functions

// Do some magic here specifically for the 'about' page...

webpack.mix.js:

mix.js(['resources/assets/js/*/*.js'); // For all pages

如果这是一个更好的解决方案,那么我如何也使用 SASS 包含文件?有没有办法可以改善上述情况?

最佳答案

我想说你必须在这里考虑 3 件主要的事情(它们并不完全相同):

  • 大小 - 您的资源将占用的空间量以及正在下载的文件大小。
  • 请求数 - 页面中加载了多少文件。
  • 浏览器缓存 - 文件将从缓存而不是服务器中提取。

在您的特定情况下,这取决于您的 app.js 文件本身有多大,如果没有来自 app.js 的代码的代码,您的页面特定文件会有多大,你有多少页面特定的文件,如果你在不同的文件中使用了一些相同的资源,例如在不同的文件中需要相同的包。


一个文件

如果您的页面特定文件相当小,那么我会将它们包含在您的主 app.js 文件中:

require('./index/index')
require('./about/about')
//etc

webpack.mix.js:

.js('resources/assets/js/app.js', 'public/js')

这意味着您只在服务器上存储一个编译文件,只对您的 javascript 发出一个请求,并且应该为整个站点的每个后续页面加载进行缓存。


一个主文件和一个页面特定文件

如果您有大量页面特定文件或者您的页面特定文件不是那么小,那么我建议您独立于页面特定文件编译您的 app.js。不要忘记将此方法的结果与 One File 方法进行比较,因为 One File 方法可能仍然更有效。

webpack.mix.js

.js('resources/assets/js/app.js', 'public/js')
.js('resources/assets/js/index/index.js', 'public/js/index')
.js('resources/assets/js/about/about.js', 'public/js/about')

这意味着您的大部分代码 (app.js) 仍将被缓存,并且只会对页面特定代码发出一个请求(然后应为每个该页面的后续加载)。

请注意,如果您在 app.js 文件和页面特定文件中都需要包,则它们不会在两者之间共享,因此会增加这些请求的总体大小。可以添加到 window 对象的包(例如 jQuery)应该只包含在您的 app.js 中。

解决此问题的一种方法是使用 Vendor Extraction (Laravel Mix docs):

.extract(['jquery'])

这将产生两个额外的文件,您需要将它们包含在您的 html 中:

<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script> 

一个主文件和几个页面特定文件

如果您有一个或两个相当大的页面特定文件,但其余的不是,您可以将大部分页面特定文件编译到 app.js 并让较大的文件编译到他们自己的文件中。


所有页面特定文件

如果您的所有页面特定文件都非常大,您的 app.js 文件没有那么大并且页面特定文件中的代码/逻辑不能,我只会走这条路被重构,以便它可以在不同的文件之间共享。

这种方式类似于您问题中的示例,但是,而不是:

webpack.mix.js

mix.js([
    'resources/assets/js/app.js',
    'resources/assets/js/index/index.js'
], 'public/js/index/index.js').version();

你会:

资源/ Assets /js/index/index.js

require('../app.js')

//rest of file

webpack.mix.js

mix.js('resources/assets/js/index/index.js', 'public/js/index/index.js').version();

尽管如此,我永远不会直接采用这种方法,而且在极少数情况下它会是最有效的。


总结

我总是会采用 One File 方法,然后再考虑进行优化(除非在开发过程中确实有问题),因为过早的优化会导致代码异味和更难的可维护性。

这对你来说可能也是一篇好文章https://medium.com/@asyncmax/the-right-way-to-bundle-your-assets-for-faster-sites-over-http-2-437c37efe3ff

关于node.js - 使用 Laravel Mix 合并多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42622118/

相关文章:

javascript - 在 Typescript 包中使用 package.json 导出

laravel - 如何清理 Laravel Telescope 调试日志

php - Laravel 4 : Target Interface is not instantiable

Laravel 数组字段总和验证

node.js - 如何在 node.js 流中与这个 <File> 对象交互?

node.js - 链接 gulp 任务并传递变量

node.js - Npm 安装错误键入 : command not found

javascript - 如何在 Node.js 中执行一组同步和异步函数

javascript - 将参数传递给 node.js 中的 async.parallel

javascript - 使用 gulp-connect 插件在 gulp 中配置中间件