作者:Piotr Ładoński。本文翻译自:dev.to/voodu/vue-3…
最近我开始玩Vue。当然,从“Hello World”计算器开始,有很好的记录的Vue 2不是一个选择,所以我决定在Vue 3中使用简单的PWA。建立一个项目并不像看起来那么容易,所以我将在这里为任何感兴趣的人描述它(并为我自己提供未来的参考)。
我将描述所有的东西,所以希望它对完全初学者有用。我不会解释Vue、PWA或服务人员的哲学——它只是关于设置这些东西。
我正在使用Win10,所以我将从这个PoV描述这个过程(但是,它只对节点安装重要)。
node、npm和Vue
与所有JS项目一样,使用Node&npm更简单。
如果您还没有,我建议您使用nvm安装Node。可能最简单的方法就是到这里,下载最新的nvm-setup.zip,提取并运行安装程序。之后,您应该可以在命令提示符中使用nvm。如果你想安装最新的稳定版本只是去与:
nvm install latest
对于某些特定的版本,您可以执行
nvm install 15.4.0
那么,记得使用哦!
nvm use 15.4.0
对于Node,npm也应该自动安装。对我来说,节点版本是15.4.0,npm是7.3.0。 为了让我们的生活更轻松,还有Vue CLI可以帮助我们建立项目。安装它:
npm install -g @vue/cli
它将允许您从终端使用vue命令。对我来说,vue--version返回@vue/cli4.5.9。 现在,我们可以从我们的迷你项目开始。
创建项目
使用Vue CLI创建新项目非常简单。就跟:
vue create our-app-name
然后使用箭头只需选择选项。我挑了:
手动选择功能
然后选择空格键渐进式Web应用(PWA)支持。按回车键继续,然后选择Vue版本到3. x,ES Lint仅具有防错功能,Lint保存,在专用配置文件中,键入n并按回车键生成项目(需要1-2分钟)。
当然你可以选择不同的选项。只有PWA支持是必要的
运行它
生成的项目可以开箱即用。首先,记得导航到创建的项目文件夹,然后运行开发服务器:
cd our-app-name
npm run serve
输出应提供可以访问生成的应用的地址。对我来说,这是超文本传输协议://localhost: 8080/(如果你想阻止它,只要CTRL+C它) 请注意,当前_Service Worker不工作-如果您在Dev Tools中转到Application>Service Worker,您将看不到它。生成的项目使服务_人员仅在生产构建中活跃。让我们检查一下。 要创建生产构建,请运行
npm run build
给它一些时间,它会在你的项目_文件夹中创建dist_目录。现在你需要把它托管在某个地方。我推荐Chrome的Web Server,因为它非常容易使用,并且工作正常(我也尝试了Python简单的超文本传输协议服务器,但是它对我来说不能正常工作,所以要小心)。只需在服务器中选择您的dist文件夹并运行它。在超文本传输协议://127.0.0.1:8000你应该能够访问你的网站。现在,您可以在Dev Tools的_Application选项_卡中找到有关Service Worker的信息,并查看有关它的一些控制台日志。
驯服 Service Worke
太好了!所有东西都跑起来了!这时又有什么问题呢?当您希望自己使用Service Worker控制缓存并在开发过程中检查它而不需要不断创建生产版本时,就会出现问题。
我现在要展示三样东西:
- 如何在开发服务器中运行Service Worker
- 如何控制缓存行为
- 如何在生产构建中使用外部模块
开发服务器中的SW
警告——默认情况下,SW在开发中被禁用,因为它可能会缓存一些新编辑的scripts/assets,您将无法看到您的更改。记住这一点,如果你不需要它来避免“为什么它不改变?!”问题。
另一个警告——这可能不是最好的方法… 但它的简单和工程:)
案例:我们希望Service Worker在开发模式中处于活动状态,并且能够控制其缓存策略。
不深入细节,让我们实现它。
首先,你需要在你的项目中安装service work rW-webpack-plugin:
npm install -D serviceworker-webpack-plugin
然后在你的项目的根(旁边的src文件夹)添加新的文件vue.config.js内容:
// vue.config.js
const path = require("path");
const ServiceWorkerWebpackPlugin = require("serviceworker-webpack-plugin");
module.exports = {
configureWebpack: {
plugins: [
new ServiceWorkerWebpackPlugin({
entry: path.join(__dirname, "./src/service-worker.js")
})
]
}
};
并修改src/main.js以包括这些行(在create App之前):
// src/main.js
// other imports...
import runtime from "serviceworker-webpack-plugin/lib/runtime";
if ("serviceWorker" in navigator) {
runtime.register();
}
// createApp...
最后,在src中添加带有一些Hello world内容的服务worker.js:
// src/service-worker.js
console.log("Hello world from our SW!");
然后运行开发服务器
npm run serve
当您在浏览器中导航到您的应用程序时,您应该会在控制台中看到来自Service-Worker的消息。成功!
控制缓存-Workbox
从头开始写软件可能很有趣… 但是让我们把它变得简单,并使用Workbox。它已经安装,所以您只需要在SW脚本中导入它。我不会解释下面片段中的所有内容,因为它在工作框的入门页上已经非常清楚了。这只是为匹配某些正则表达式(在这种情况下是图像)的数据设置特定规则的例子。
// src/service-worker.js
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';
import { Plugin } from 'workbox-expiration';
import { precacheAndRoute } from 'workbox-precaching';
precacheAndRoute(self.serviceWorkerOption.assets);
registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
new StaleWhileRevalidate({
cacheName: 'images',
plugins: [
new Plugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
})
);
只是简短的评论关于pre ache And Route行-self.serviceWorkerOption.assets来自我们之前安装的service Worker-webpack-plugin,并包含我们应用程序中的所有静态资产。 现在,即使您处于开发模式,您也应该在控制台中看到一些工作框日志。在第一页加载它将是
以及随后类似的事情
如果您在Dev Tools中转到_网络_选项卡并模拟脱机模式,应用程序仍应正常加载。 太棒了!解决了两个问题-我们对我们的服务人员有细粒度的控制,并且它在开发模式下工作。
固定探针上的SW
与此同时,不幸的是,我们搞砸了应用的生产版本。如果您运行npm run build并查看它,一开始可能看起来不错,但事实并非如此。首先,在随后的刷新中,你可以看到新内容可用;请刷新。
日志所有的时间,虽然你不改变任何东西。此外,如果您选中_应用程序_选项卡,您将看到两个服务工作者一直在活动,第二个等待激活。即使你强制更新,刷新后也会有另一个等待。
问题来自双重注册-一个SW注册在main.js,第二个来自生成的registerServiceWorker.js.这是我无法很好地克服的问题,但我想出了两个可以接受的解决方案:
-
如果您不关心来自registerServiceWorker.js的日志记录,请不要将其导入src/main.js,问题就会消失。
-
如果你想保留这些控制台日志,但是可以让SW只在prod上工作(但是保留对缓存规则的控制),并且在SW中导入模块的方式更加复杂,这需要更多的努力:首先,将vue.config.js内容更改为:
module.exports = {
pwa: {
workboxPluginMode: "InjectManifest",
workboxOptions: {
swSrc: "src/service-worker.js"
}
}
};
然后恢复您在src/main.js中所做的更改(即删除任何与service Worker-webpack-plugin相关的内容)。最后,您需要更改src/service-worker.js不使用导入和使用不同参数的前置。如果您想使用一些外部模块,请使用带有CDN链接的import Scripts(例如,下面的动词;用法很愚蠢,但演示了这样做的方式)。注意现在如何展开工作框名称:
importScripts('https://momentjs.com/downloads/moment.min.js');
workbox.precaching.precacheAndRoute(self.__precacheManifest);
const cacheExpTime = moment().add(1, 'day');
const cacheTimeLeft = moment.duration(cacheExpTime.diff(moment())).asSeconds();
workbox.routing.registerRoute(
/\.(?:png|ico|gif|jpg|jpeg|svg)$/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'images',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: cacheTimeLeft, // 1 day
}),
],
})
);
当然还有第三个选项,它可以让你继续记录和其他一切,但是我不知道如何正确配置Webpack。如果你有任何简单的解决方案,我会非常乐意在评论中阅读:)
结论
如果您想要非常简单的缓存技术,并且保持只由服务工作者处理静态资产是可以的,那么生成的项目绝对足够了。但是,如果希望对Service Worker进行更多的控制,则可以缓存ex。API调用,您需要以某种方式调整它。我希望上面的提示,如何做到这一点以及如何处理开发模式将是有用的。 如上所述,这绝对不是最好和唯一的解决方案。这只是一些Vue新手(像我)以合理的方式与服务人员打交道的一个初步选择。