tonysm / importmap-laravel
使用 importmap 管理 Laravel 中的现代 JavaScript,无需转换或打包。
Requires
- php: ^8.1|^8.2
- illuminate/contracts: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
- spatie/laravel-package-tools: ^1.9
Requires (Dev)
- guzzlehttp/guzzle: ^7.4
- laravel/pint: ^1.10
- nunomaduro/collision: ^6.0|^8.1
- orchestra/testbench: ^7.17|^8.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^10.5
- dev-main
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.0
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 2.0.0-beta1
- 1.8.3
- 1.8.2
- 1.8.1
- 1.8.0
- 1.7.0
- 1.6.0
- 1.5.0
- 1.4.1
- 1.4.0
- 1.3.0
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.0
- 0.4.1
- 0.4.0
- 0.3.0
- 0.2.0
- 0.0.1
- dev-dependabot/github_actions/dependabot/fetch-metadata-2.2.0
- dev-dont-optimize-with-url
This package is auto-updated.
Last update: 2024-09-19 16:28:34 UTC
README
简介
使用 importmap 管理 Laravel 中的现代 JavaScript,无需转换或打包。
灵感
此包受 Importmap Rails 钥石的启发。此 README 的一些部分直接从那里复制并适配到 Laravel 版本。
它是如何工作的?
导入映射 允许您使用与版本/散列文件映射的逻辑名称导入 JavaScript 模块 - 直接从浏览器中导入。因此,您可以使用为 ES 模块 (ESM) 制作的 JavaScript 库来构建现代 JavaScript 应用程序,而无需转换或打包,无需 Webpack、Yarn、npm 或 JavaScript 工具链的任何其他部分。
使用这种方法,您将发送许多小的 JavaScript 文件,而不是一个大的 JavaScript 文件。多亏了 HTTP/2,它在初始传输中不再产生重大性能损失,并且由于更好的缓存动态,在长期运行中提供了实质性的好处。以前,对包含在大包中的任何 JavaScript 文件的任何更改都会使整个包的缓存失效,而现在只需使单个文件的缓存失效。
导入映射在所有主流、现代浏览器中都有原生支持。如果您需要与没有原生支持的旧版浏览器一起工作,您可能想探索使用 可用的模拟器。
安装
您可以通过 Composer 安装此包
composer require tonysm/importmap-laravel
此包有一个 install
命令,您可以运行它以替换默认的 Laravel 脚手架为使用 importmap 的脚手架
php artisan importmap:install
接下来,我们需要将以下组件添加到我们的视图或布局文件中
<x-importmap::tags />
在您的 <head>
标签之间添加此内容。 entrypoint
应该是 "main" 文件,通常是 resources/js/app.js
文件,它将被映射到 app
模块(使用模块名称,而不是文件)。
默认情况下,x-importmap::tags
组件假定您的入口点模块是 app
,这与 Laravel 默认脚手架中现有的 resources/js/app.js
文件相匹配。您可能想要自定义入口点,这可以通过 entrypoint
属性来完成
<x-importmap::tags entrypoint="admin" />
该包将自动使用 Laravel 的符号链接功能将 resources/js
文件夹映射到您的 public/js
文件夹。安装此包后,您只需运行
php artisan storage:link
如果您正在使用 Laravel Sail,请确保在命令前加上 sail
,因为符号链接需要在容器内创建。
符号链接仅在本地环境中注册。对于生产环境,建议运行 importmap:optimize
命令
php artisan importmap:optimize
本功能应扫描您所有已固定的文件/文件夹(不包括URL)并将它们发布到public/dist/js
,根据文件内容添加到文件名中的校验和,例如public/dist/js/app-123123.js
,然后在public/
文件夹中生成一个.importmap-manifest.json
文件。该文件将覆盖您的固定项。如果您在开发中意外运行它,请确保删除该文件或简单地运行php artisan importmap:clear
,这将删除它。您可能还想将/public/dist
添加到您的.gitignore
文件中,以及添加*importmap-manifest.json
。
用法
简而言之,importmap通过向浏览器提供一个映射,告诉它在哪里查找您的JavaScript导入语句。例如,您可以在routes/importmap.php
文件中这样固定Alpinejs的依赖项
<?php use Tonysm\ImportmapLaravel\Facades\Importmap; // Other pins... Importmap::pin("alpinejs", to: "/js/vendor/alpinejs.js"); //@3.8.1
然后,在您的JavaScript文件中,您可以安全地这样做
import Alpine from 'alpinejs';
本地文件固定
本地固定应手动添加到routes/importmap.php
文件中,如下所示
Importmap::pin("app", to: "/js/app.js");
这意味着app
模块将在浏览器中指向/js/app.js
。这是浏览器将用于获取文件的URI,而不是文件的路径本身。对本地文件的固定假设有一个相对路径resources/js/
来找到它们。
本地目录固定
声明所有本地文件可能会很繁琐,因此您可能希望映射整个文件夹,如下所示
Importmap::pinAllFrom("resources/js/", to: "js/");
当我们生成importmap JSON时,我们将扫描该目录,寻找其中任何.js
或.jsm
文件,并根据它们的相对位置生成正确的importmap。
如果文件夹中有一个index.js
文件,我们不会在模块名称中获取index
,因此我们可以这样导入它
import libs from 'libs';
而不是
import libs from 'libs/index';
外部依赖项固定
如果您依赖任何外部库,可以使用importmap:pin
命令来固定它,如下所示
php artisan importmap:pin alpinejs
它将下载alpinejs
库,然后它将向您的routes/importmap.php
文件添加以下行
Importmap::pin("alpinejs", to: "/js/vendor/alpinejs.js"); // @3.8.1
pin
命令使用jspm.io API解析依赖项(以及我们的依赖项的依赖项),寻找我们可以固定的ESM模块,并将其解析为CDN URL并作为依赖项下载。我们可以通过指定--from
标志来控制我们想要使用的CDN
php artisan importmap:pin alpinejs --from=unpkg
这将从unpkg而不是默认的JSPM CDN下载库。
请注意,pin
命令将始终解析依赖项(以及我们的依赖项的依赖项)并将所有文件下载到您的resources/js/vendor
文件夹中,您应该将其添加到您的版本控制中,并自行将其作为供应商。
Importmap::pin("alpinejs", to: "/js/vendor/alpinejs.js"); // @3.8.1
版本号作为注释添加到您的固定项中,以便您知道导入的哪个版本。不要删除它,因为稍后当您需要升级依赖项时它将非常有用。
模块预加载
为了避免浏览器必须一个接一个地加载文件才能到达最深的导入,我们默认使用modulepreload链接。如果您不希望预加载依赖项,因为它会按需加载以提高效率,请将preload: false
附加到固定项中。
Importmap::pinAllFrom("resources/js/", to: "js/", preload: true); Importmap::pin("alpinejs", to: "https://unpkg.com/alpinejs@3.8.1/dist/module.esm.js", preload: true); // @3.8.1
这将向HTML文档的head标签中添加正确的links
标签,如下所示
<link rel="modulepreload" href="https://unpkg.com/alpinejs@3.8.1/dist/module.esm.js">
依赖项维护命令
维护一个健康的依赖项列表可能会很困难。以下是一些有助于您完成此任务的命令。
过时的依赖项
为了保持您的依赖项更新,请确保您不时运行importmap:outdated
命令
php artisan importmap:outdated
此命令将扫描您的 routes/importmap.php
文件,查找您当前的版本,然后使用 NPM 注册表 API 查找您正在使用的包的最新版本。它还可以处理使用 importmap:pin
命令的 --download
标志添加的本地服务供应商库。
审计依赖项
如果您想对依赖项进行安全审计以查看您是否使用了已泄露的版本,请定期运行 importmap:audit
命令。更好的做法是将该命令添加到您的 CI 构建中。
php artisan importmap:audit
这将同样扫描您的 routes/importmap.php
文件,查找您的当前版本,然后使用 NPM 注册表 API 查找您的包中的漏洞。它还可以处理使用 importmap:pin
命令的 --download
标志添加的本地服务供应商库。
已知问题
关于 React 的 JSX 和 Vue 的 SFC
您可以使用 importmaps 同时使用 React 和 Vue,但遗憾的是,您将无法使用 JSX 或 SFC 的功能。这是因为这些文件类型需要一个编译/转译步骤,将它们转换为浏览器可以理解的格式。有其他方法可以使用这两个库,但我要说,这些方法在其社区中并不是“常见”的。您可以尝试使用 React with HTM。您也可以使用 Vue 而无需 SFC,唯一的区别是您的模板将位于 Blade 文件中,而不是 SFC 文件中。
进程环境配置
您可能习惯在 JS 文件中这里那里添加几行 process.env.MIX_*
。这种方式是 Webpack 在构建时会用构建期间 process.env
的值替换您的调用。由于我们不再有“构建时间”,所以这不会工作。相反,您应该在布局文件中添加 <meta>
标签,以使您希望提供给 JavaScript 文件的内容可用,并使用 document.head.querySelector('meta[name=my-config]').content
而不是依赖于 process.env
。
考虑使用类似 current.js
的工具,通过全局可用的 Current
对象轻松消费您的 <meta>
配置。
测试
composer test
变更日志
有关最近更改的更多信息,请参阅 CHANGELOG。
贡献
有关详细信息,请参阅 CONTRIBUTING。
安全漏洞
有关报告安全漏洞的详细信息,请参阅 我们的安全策略。
致谢
许可证
MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件。