如何使用 Laravel Mix 和 WorkBox?

2024-05-13

我正在尝试为我的应用程序构建一个 PWA;并花了近 48 小时试图弄清楚如何将 Workbox 与 Laravel Mix 结合使用。具有讽刺意味的是,谷歌说 Workbox 是为了让事情变得简单!

Buh!

好吧,到目前为止我已经弄清楚了 -

  1. 我需要使用InjectManifest Plugin因为我想将推送通知服务集成到我的 Service Worker 中

  2. 我不知道如何指定路径swSrc and swDest.

  3. 什么代码应该进入我的webpack.mix.js以及我是否应该在我的房间里安排一名临时服务人员resources/js文件夹以在其中创建一个新的 Service Workerpublic/文件夹。

有人可以帮忙吗?

PS:我几乎阅读了所有博客和帮助文章;但没有人谈论如何可靠地将 Workbox 与 Laravel mix 结合使用。非常感谢这里的一些帮助。


我最近对此做了很多研究,虽然这可能不是一个full回答您的问题,它应该为您或访问此页面的其他人提供足够的指导来开始...

当我学习和研究更多时,我会添加这个答案。

为了这个答案的目的,我假设你的服务人员被称为service-worker.js但是,您显然可以随意称呼它。

第 1 步 - Laravel Mix

假设您正在使用动态导入 https://router.vuejs.org/guide/advanced/lazy-loading.html#grouping-components-in-the-same-chunk在你的项目中(如果你不是,你应该是),你需要将 Laravel Mix 降级到版本 3。有一个承认的错误 https://laravel-mix.com/docs/4.1/upgrade#notes在 Laravel Mix 4 中,它会阻止 CSS 正确捆绑,并且在 Webpack 5 发布之前不会修复此问题。

此外,本答案中概述的步骤是专门为 Laravel Mix 3 配置的。

第 2 步 - 导入或导入脚本

第二个需要解决的问题是是否使用workbox-webpack-plugin用于注射workbox全局使用importScripts或者您是否应该禁用它(使用importWorkboxFrom: 'disabled'),然后单独导入您需要的特定模块...

文档指出:

使用 JavaScript 捆绑器时,您不需要(实际上也不应该使用)workbox全球或workbox-sw模块,因为您可以直接导入各个包文件。

这意味着我们should正在使用import而不是注入importScripts.

然而,这里存在各种问题:

  • 我们不想要service-worker.js包含在构建清单中,因为这将被注入到预缓存清单中
  • 我们不想要service-worker.js版本控制在production即名称应该始终是service-worker.js, not service-worker.123abc.js.
  • InjectManifest将无法注入清单,因为service-worker.js文件在运行时将不存在。

因此,为了利用import代替importScripts,我们必须有两个单独的 webpack(混合)配置(有关如何执行此操作的指导,请参阅结论)。我不能 100% 确定这是正确的,但一旦收到以下任一问题的答案,我将更新我的答案(请支持他们以增加收到答案的机会):

  • 如何将 Workbox 与 Bundler(Webpack 等)一起使用 https://stackoverflow.com/questions/57726659/how-to-use-workbox-with-a-bundler-webpack-etc
  • https://github.com/GoogleChrome/workbox/issues/2207 https://github.com/GoogleChrome/workbox/issues/2207

第 3 步 - 文件结构

假设您正在使用InjectManifest并不是GenerateSW,您需要编写自己的 Service Worker,每次构建时 Webpack 插件都会将 JS 清单注入其中。很简单,这意味着您需要在源目录中创建一个将用作服务工作人员的文件。

我的位于src/js/service-worker.js(如果您正在构建完整的 Laravel 项目,这将会有所不同,我只是在独立应用程序中使用 Laravel Mix)

第 4 步 - 注册 Service Worker

有多种方法可以做到这一点;有些人喜欢将内联 JS 注入到 HTML 模板中,但其他人,包括我自己,只需在其顶部注册 Service Workerapp.js。无论哪种方式,代码看起来应该类似于:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
        navigator.serviceWorker.register('/service-worker.js');
    });
}

第 5 步 - 编写你的 Service Worker;workbox全局或模块导入

正如文档前面的引用中提到的,鼓励将特别需要的模块导入到您的 Service Worker 中,而不是使用workbox全局或workbox-sw module.

有关如何使用各个模块以及如何实际编写 Service Worker 的更多信息,请参阅以下文档:

https://developers.google.com/web/tools/workbox/guides/using-bundlers https://developers.google.com/web/tools/workbox/guides/using-bundlers

结论

根据我的所有研究(仍在进行中),我采取了下面概述的方法。

在阅读之前,请记住,这是为独立的静态 PWA 配置的(即不是完整的 Laravel 项目)。

/src/service-worker.js(服务人员)

当使用捆绑器时,例如webpack,建议使用import以确保您只包含必要的workbox模块。这是我的服务人员骨架:

import config from '~/config'; // This is where I store project based configurations
import { setCacheNameDetails } from 'workbox-core';
import { precacheAndRoute } from 'workbox-precaching';
import { registerNavigationRoute } from 'workbox-routing';

// Set the cache details
setCacheNameDetails({
    prefix: config.app.name.replace(/\s+/g, '-').toLowerCase(),
    suffix: config.app.version,
    precache: 'precache',
    runtime: 'runtime',
    googleAnalytics: 'ga'
});

// Load the assets to be precached
precacheAndRoute(self.__precacheManifest);

// Ensure all requests are routed to index.html (SPA)
registerNavigationRoute('/index.html');

/package.json

拆分 Mix 配置

"scripts": {  
  "development": "npm run dev-service-worker && npm run dev-core",  
  "dev": "npm run development",  
  "dev-service-worker": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=service-worker.mix",  
  "dev-core": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=core.mix",  
  "watch": "npm run dev-core -- --watch",  
  "watch-poll": "npm run watch -- --watch-poll",  
  "production": "npm run prod-service-worker && npm run prod-core",  
  "prod": "npm run production",  
  "prod-service-worker": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=service-worker.mix",  
  "prod-core": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=core.mix"  
}

命令解释

  • 所有标准命令都将以与平常相同的方式工作(即npm run devETC。)。请参阅有关的已知问题npm run watch
  • npm run <environment>-service-worker将仅在指定环境中构建 Service Worker
  • npm run <environment>-core将仅在指定环境中构建核心应用程序

已知的问题

  • 如果您使用的 html 模板利用了 webpack 清单,那么您可能会遇到以下问题npm run watch。到目前为止我还无法让它正常工作

降级到 Laravel Mix 3

"devDependencies": {  
    "laravel-mix": "^3.0.0"  
}

这也可以通过运行来实现npm install [email protected] /cdn-cgi/l/email-protection

/static/index.ejs

该 HTML 模板用于生成单页应用程序index.html。该模板依赖于注入的 webpack 清单。

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" class="no-js">
    <head>

        <!-- General meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="<%= config.meta.description %>">
        <meta name="rating" content="General">
        <meta name="author" content="Sine Macula">
        <meta name="robots" content="index, follow">
        <meta name="format-detection" content="telephone=no">

        <!-- Preconnect and prefetch urls -->
        <link rel="preconnect" href="<%= config.api.url %>" crossorigin>
        <link rel="dns-prefetch" href="<%= config.api.url %>">

        <!-- Theme Colour -->
        <meta name="theme-color" content="<%= config.meta.theme %>">

        <!-- General link tags -->
        <link rel="canonical" href="<%= config.app.url %>">

        <!-- Manifest JSON -->
        <link rel="manifest" href="<%= StaticAsset('/manifest.json') %>" crossorigin>


        <!-- ----------------------------------------------------------------------
        ---- Icon Tags
        ---- ----------------------------------------------------------------------
        ----
        ---- The following will set up the favicons and the apple touch icons to be
        ---- used when adding the app to the homescreen of an iPhone, and to
        ---- display in the head of the browser.
        ----
        ---->
        <!--[if IE]>
            <link rel="shortcut icon" href="<%= StaticAsset('/favicon.ico') %>">
        <![endif]-->
        <link rel="apple-touch-icon" sizes="72x72" href="<%= StaticAsset('/apple-touch-icon-72x72.png') %>">
        <link rel="apple-touch-icon" sizes="120x120" href="<%= StaticAsset('/apple-touch-icon-120x120.png') %>">
        <link rel="apple-touch-icon" sizes="180x180" href="<%= StaticAsset('/apple-touch-icon-180x180.png') %>">
        <link rel="icon" type="image/png" sizes="16x16" href="<%= StaticAsset('/favicon-16x16.png') %>">
        <link rel="icon" type="image/png" sizes="32x32" href="<%= StaticAsset('/favicon-32x32.png') %>">
        <link rel="icon" type="image/png" sizes="192x192"  href="<%= StaticAsset('/android-chrome-192x192.png') %>">
        <link rel="icon" type="image/png" sizes="194x194"  href="<%= StaticAsset('/favicon-194x194.png') %>">
        <link rel="mask-icon" href="<%= StaticAsset('/safari-pinned-tab.svg') %>" color="<%= config.meta.theme %>">
        <meta name="msapplication-TileImage" content="<%= StaticAsset('/mstile-144x144.png') %>">
        <meta name="msapplication-TileColor" content="<%= config.meta.theme %>">


        <!-- ----------------------------------------------------------------------
        ---- Launch Images
        ---- ----------------------------------------------------------------------
        ----
        ---- Define the launch 'splash' screen images to be used on iOS.
        ----
        ---->
        <link rel="apple-touch-startup-image" href="<%= StaticAsset('/assets/images/misc/splash-640x1136.png') %>" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="<%= StaticAsset('/assets/images/misc/splash-750x1294.png') %>" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="<%= StaticAsset('/assets/images/misc/splash-1242x2148.png') %>" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="<%= StaticAsset('/assets/images/misc/splash-1125x2436.png') %>" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="<%= StaticAsset('/assets/images/misc/splash-1536x2048.png') %>" media="(min-device-width: 768px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="<%= StaticAsset('/assets/images/misc/splash-1668x2224.png') %>" media="(min-device-width: 834px) and (max-device-width: 834px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="<%= StaticAsset('/assets/images/misc/splash-2048x2732.png') %>" media="(min-device-width: 1024px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">


        <!-- ----------------------------------------------------------------------
        ---- Application Tags
        ---- ----------------------------------------------------------------------
        ----
        ---- Define the application specific tags.
        ----
        ---->
        <meta name="application-name" content="<%= config.app.name %>">
        <meta name="apple-mobile-web-app-title" content="<%= config.app.name %>">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="<%= config.app.status_bar %>">
        <meta name="mobile-web-app-capable" content="yes">
        <meta name="full-screen" content="yes">
        <meta name="browsermode" content="application">


        <!-- ----------------------------------------------------------------------
        ---- Social Media and Open Graph Tags
        ---- ----------------------------------------------------------------------
        ----
        ---- The following will create objects for social media sites to read when
        ---- scraping the site.
        ----
        ---->

        <!-- Open Graph -->
        <meta property="og:site_name" content="<%= config.app.name %>">
        <meta property="og:url" content="<%= config.app.url %>">
        <meta property="og:type" content="website">
        <meta property="og:title" content="<%= config.meta.title %>">
        <meta property="og:description" content="<%= config.meta.description %>">
        <meta property="og:image" content="<%= StaticAsset('/assets/images/brand/social-1200x630.jpg') %>">

        <!-- Twitter -->
        <meta name="twitter:card" content="app">
        <meta name="twitter:site" content="<%= config.app.name %>">
        <meta name="twitter:title" content="<%= config.meta.title %>">
        <meta name="twitter:description" content="<%= config.meta.description %>">
        <meta name="twitter:image" content="<%= StaticAsset('/assets/images/brand/social-440x220.jpg') %>">


        <!-- ----------------------------------------------------------------------
        ---- JSON Linked Data
        ---- ----------------------------------------------------------------------
        ----
        ---- This will link the website to its associated social media page. This
        ---- adds to the credibility of the website as it allows search engines to
        ---- determine the following of the company via social media
        ----
        ---->
        <script type="application/ld+json">
            {
                "@context": "http://schema.org",
                "@type": "Organization",
                "name": "<%= config.company.name %>",
                "url": "<%= config.app.url %>",
                "sameAs": [<%= '"' + Object.values(config.company.social).map(x => x.url).join('","') + '"' %>]
            }
        </script>

        <!-- Define the page title -->
        <title><%= config.meta.title %></title>

        <!-- Generate the prefetch/preload links -->
        <% webpack.chunks.slice().reverse().forEach(chunk => { %>
            <% chunk.files.forEach(file => { %>
                <% if (file.match(/\.(js|css)$/)) { %>
                    <link rel="<%= chunk.initial ? 'preload' : 'prefetch' %>" href="<%= StaticAsset(file) %>" as="<%= file.match(/\.css$/) ? 'style' : 'script' %>">
                <% } %>
            <% }) %>
        <% }) %>

        <!-- Include the core styles -->
        <% webpack.chunks.forEach(chunk => { %>
            <% chunk.files.forEach(file => { %>
                <% if (file.match(/\.(css)$/) && chunk.initial) { %>
                    <link rel="stylesheet" href="<%= StaticAsset(file) %>">
                <% } %>
            <% }) %>
        <% }) %>

    </head>
    <body ontouchstart="">

        <!-- No javascript error -->
        <noscript>JavaScript turned off...</noscript>

        <!-- The Vue JS app element -->
        <div id="app"></div>

        <!-- Include the core scripts -->
        <% webpack.chunks.slice().reverse().forEach(chunk => { %>
            <% chunk.files.forEach(file => { %>
                <% if (file.match(/\.(js)$/) && chunk.initial) { %>
                    <script type="text/javascript" src="<%= StaticAsset(file) %>"></script>
                <% } %>
            <% }) %>
        <% }) %>

    </body>
</html>

/service-worker.mix.js(构建 Service Worker)

这种混合配置将构建您的 Service Worker (service-worker.js),并将其放入根目录中/dist.

Note:我喜欢清洁我的dist每次构建项目时,文件夹中都会包含此功能,并且由于此功能必须在构建过程的此阶段运行,因此我已将其包含在以下配置中。

const mix   = require('laravel-mix');
const path  = require('path');

// Set the public path
mix.setPublicPath('dist/');

// Define all the javascript files to be compiled
mix.js('src/js/service-worker.js', 'dist');

// Load any plugins required to compile the files
const Dotenv = require('dotenv-webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// Define the required plugins for webpack
const plugins = [

    // Grant access to the environment variables
    new Dotenv,

    // Ensure the dist folder is cleaned for each build
    new CleanWebpackPlugin

];

// Extend the default Laravel Mix webpack configuration
mix.webpackConfig({
    plugins,
    resolve: {
        alias: {
            '~': path.resolve('')
        }
    }
});

// Disable mix-manifest.json (remove this for Laravel projects)
Mix.manifest.refresh = () => void 0;

/core.mix.js(构建应用程序)

此混合配置将构建您的主应用程序并将其放置在/dist/js.

该混合配置有多个关键部分,每个部分都已在注释中清楚地概述。这些是顶级区域:

  • 代码分割为app.js, manifest.js, and vendor.js(和动态导入)
  • Laravel Mix 版本控制无法根据 HTML 模板的需要工作,因此laravel-mix-versionhash改为使用
  • html-webpack-plugin用于生成index.html基于index.ejs模板(见上文)
  • webpack-pwa-manifest用于生成基于清单的
  • copy-webpack-plugin用于将静态文件复制到/dist目录,并将任何必要的图标复制到站点根目录
  • imagemin-webpack-plugin用于压缩任何静态图像production
  • workbox-webpack-plugin用于将 webpack 清单注入到 Service Worker 中使用的预缓存数组中。InjectManifest被使用,而不是GenerateSW
  • 构建过程完成后,将应用任何必要的清单转换

上面可能有一些补充,但几乎所有内容都由以下代码中的注释描述:

const config    = require('./config'); // This is where I store project based configurations
const mix       = require('laravel-mix');
const path      = require('path');
const fs        = require('fs');

// Include any laravel mix plugins
// NOTE: not needed in Laravel projects
require('laravel-mix-versionhash');

// Set the public path
mix.setPublicPath('dist/');

// Define all the SASS files to be compiled
mix.sass('src/sass/app.scss', 'dist/css');

// Define all the javascript files to be compiled
mix.js('src/js/app.js', 'dist/js');

// Split the js into bundles
mix.extract([
    // Define the libraries to extract to `vendor`
    // e.g. 'vue'
]);

// Ensure the files are versioned when running in production
// NOTE: This is not needed in Laravel projects, you simply need
// run `mix.version`
if (mix.inProduction()) {
    mix.versionHash({
        length: 8
    });
}

// Set any necessary mix options
mix.options({

    // This doesn't do anything yet, but once the new version
    // of Laravel Mix is released, this 'should' extract the
    // styles from the Vue components and place them in a
    // css file, as opposed to placing them inline
    //extractVueStyles: true,

    // Ensure the urls are not processed
    processCssUrls: false,

    // Apply any postcss plugins
    postCss: [
        require('css-declaration-sorter'),
        require('autoprefixer')
    ]

});

// Disable mix-manifest.json
// NOTE: not needed in Laravel projects
Mix.manifest.refresh = () => void 0;

// Load any plugins required to compile the files
const Dotenv                    = require('dotenv-webpack');
const HtmlWebpackPlugin         = require('html-webpack-plugin');
const WebpackPwaManifest        = require('webpack-pwa-manifest');
const { InjectManifest }        = require('workbox-webpack-plugin');
const CopyWebpackPlugin         = require('copy-webpack-plugin');
const ImageminPlugin            = require('imagemin-webpack-plugin').default;

// Define the required plugins for webpack
const plugins = [

    // Grant access to the environment variables
    new Dotenv,

    // Process and build the html template
    // NOTE: not needed if using Laravel and blade
    new HtmlWebpackPlugin({
        template: path.resolve(__dirname, 'static', 'index.ejs'),
        inject: false,
        minify: !mix.inProduction() ? false : {
            collapseWhitespace: true,
            removeComments: true,
            removeRedundantAttributes: true,
            useShortDoctype: true
        },
        templateParameters: compilation => ({
            webpack: compilation.getStats().toJson(),
            config,
            StaticAsset: (file) => {
                // This will ensure there are no double slashes (bug in Laravel Mix)
                return (config.app.static_url + '/' + file).replace(/([^:]\/)\/+/g, "$1");
            }
        })
    }),

    // Generate the manifest file
    new WebpackPwaManifest({
        publicPath: '',
        filename: 'manifest.json',
        name: config.app.name,
        description: config.meta.description,
        theme_color: config.meta.theme,
        background_color: config.meta.theme,
        orientation: config.app.orientation,
        display: "fullscreen",
        start_url: '/',
        inject: false,
        fingerprints: false,
        related_applications: [
            {
                platform: 'play',
                url: config.app.stores.google.url,
                id: config.app.stores.google.id
            },
            {
                platform: 'itunes',
                url: config.app.stores.apple.url,
                id: config.app.stores.apple.id
            }
        ],
        // TODO: Update this once the application is live
        screenshots: [
            {
                src: config.app.static_url + '/assets/images/misc/screenshot-1-720x1280.png',
                sizes: '1280x720',
                type: 'image/png'
            }
        ],
        icons: [
            {
                src: path.resolve(__dirname, 'static/assets/images/icons/android-chrome-512x512.png'),
                sizes: [72, 96, 128, 144, 152, 192, 384, 512],
                destination: path.join('assets', 'images', 'icons')
            }
        ]
    }),

    // Copy any necessary directories/files
    new CopyWebpackPlugin([
        {
            from: path.resolve(__dirname, 'static'),
            to: path.resolve(__dirname, 'dist'),
            toType: 'dir',
            ignore: ['*.ejs']
        },
        {
            from: path.resolve(__dirname, 'static/assets/images/icons'),
            to: path.resolve(__dirname, 'dist'),
            toType: 'dir'
        }
    ]),

    // Ensure any images are optimised when copied
    new ImageminPlugin({
        disable: process.env.NODE_ENV !== 'production',
        test: /\.(jpe?g|png|gif|svg)$/i
    }),

    new InjectManifest({
        swSrc: path.resolve('dist/service-worker.js'),
        importWorkboxFrom: 'disabled',
        importsDirectory: 'js'
    })

];

// Extend the default Laravel Mix webpack configuration
mix.webpackConfig({
    plugins,
    output: {
        chunkFilename: 'js/[name].js',
    }
}).then(() => {

    // As the precached filename is hashed, we need to read the
    // directory in order to find the filename. Assuming there
    // are no other files called `precache-manifest`, we can assume
    // it is the first value in the filtered array. There is no
    // need to test if [0] has a value because if it doesn't
    // this needs to throw an error
    let filename = fs
        .readdirSync(path.normalize(`${__dirname}/dist/js`))
        .filter(filename => filename.startsWith('precache-manifest'))[0];

    // In order to load the precache manifest file, we need to define
    // self in the global as it is not available in node.
    global['self'] = {};
    require('./dist/js/' + filename);

    let manifest = self.__precacheManifest;

    // Loop through the precache manifest and apply any transformations
    manifest.map(entry => {

        // Remove any double slashes
        entry.url = entry.url.replace(/(\/)\/+/g, "$1");

        // If the filename is hashed then remove the revision
        if (entry.url.match(/\.[0-9a-f]{8}\./)) {
            delete entry.revision;
        }

        // Apply any other transformations or additions here...

    });

    // Filter out any entries that should not be in the manifest
    manifest = manifest.filter(entry => {

        return entry.url.match(/.*\.(css|js|html|json)$/)
            || entry.url.match(/^\/([^\/]+\.(png|ico|svg))$/)
            || entry.url.match(/\/images\/icons\/icon_([^\/]+\.(png))$/)
            || entry.url.match(/\/images\/misc\/splash-([^\/]+\.(png))$/);

    });

    // Concatenate the contents of the precache manifest and then save
    // the file
    const content = 'self.__precacheManifest = (self.__precacheManifest || []).concat(' + JSON.stringify(manifest) + ');';
    fs.writeFileSync('./dist/js/' + filename, content, 'utf8', () => {});

});

/src/js/app.js(主要应用)

这是您注册服务人员的地方,并且显然定义了您的应用程序等......

/**
 * Register the service worker as soon as the page has finished loading.
 */
if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
        // TODO: Broadcast updates of the service worker here...
        navigator.serviceWorker.register('/service-worker.js');
    });
}

// Define the rest of your application here...
// e.g. window.Vue = require('vue');
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Laravel Mix 和 WorkBox? 的相关文章

  • 场次抽奖

    有人能解释一下什么是会话扫彩票吗 我已附加 Laravel 框架的默认会话配置文件 问题 1 它说某些会话驱动程序必须manually扫荡他们的 存储位置 有人可以描述这个过程以及为什么会这样吗 必要的 哪些会话驱动程序需要此操作 2 为什
  • Laravel - 调用未定义的方法 Illuminate\Database\Query\Builder::user()

    我正忙于Laravel 从头开始 更新记录和预加载 https laracasts com series laravel 5 from scratch episodes 10 我已经遵循了该教程 但在尝试在 CardsController
  • 重置密码 电子邮件

    我是 Laravel 开发新手 目前正在从事小型项目 我想自定义重置密码的电子邮件模板 甚至将其链接到完全不同的模板 对于身份验证脚手架 我使用了php artisan make auth命令 但是 默认重置密码功能使用默认的 Larave
  • updateExistingPivot() 不起作用

    我正在尝试像这样更新数据透视表 public function updatePermission id permissionId permissionValue Input get value user User find id perms
  • 如何在 Laravel 查询中使用多个 OR,AND 条件

    我需要 Laravel 查询帮助 我的自定义查询 返回正确结果 Select FROM events WHERE status 0 AND type public or type private 如何写这个查询Laravel Event w
  • 如何将 Laravel 5.4 与 Angular 4 集成

    我知道如何创造完整的拉拉维尔 5 4自己的项目 我也知道如何使用创建 SPA角4 Problem 我不知道如何将 Laravel 与 Angular 集成 另外 我想使用 Laravel 5 4 作为后端 使用 Angular 4 作为前端
  • .htaccess 异常导致主目录出现问题

    这是我的目录结构 localhost or livehost app bootstrap public vendor code demo 这是我的 htaccess
  • Laravel 5 中的自定义验证器

    我正在将 Laravel 应用程序从 4 升级到 5 但是 我有一个自定义验证器 但无法运行 在L4中 我做了一个验证器 php文件并将其包含在全局 php using require app path validators php 我尝试
  • 您的要求无法解析为 laravel 的一组可安装软件包

    我使用 5 7v Laravel 和 7 2 1v PHP 和 Composer 最新版本 但是当我想创建新项目时出现这些错误 Your requirements could not be resolved to an installabl
  • Laravel Vue 组件只能传递数字?

    在我的 UserMenu vue 中我写道 export default props nameVal data return 并在blade php中
  • PHP Laravel:未找到特征

    我在命名空间和使用方面遇到一些问题 我收到此错误 未找到特征 Billing BillingInterface 这些是我的 Laravel 应用程序中的文件 计费 php namespace Billing BillingInterface
  • 命令“tinker”未定义

    从 5 3 升级到 5 4 后 请按照说明操作 为了继续使用 Tinker Artisan 命令 您还应该安装 laravel tinker 软件包 composer require laravel tinker 安装软件包后 您应该添加
  • 如何在自定义组件中使用 Vue.js 插件?

    我需要输出一个表格及其内容 可以通过 Ajax 进行更新 所以我打算使用vue tables 2 https github com matfish2 vue tables 2 https github com matfish2 vue ta
  • Laravel 从 5.6 升级到 Laravel 6

    我有一个项目https github com javedbaloch4 Laravel Booking https github com javedbaloch4 Laravel Booking发展于Laravel 5 6现在我想将其升级到
  • `navigator.geolocation.getCurrentPosition()` 在 iOS PWA 上挂起

    我有这个片段 const getCurrentPosition gt new Promise
  • Laravel 中只向登录用户显示按钮

    如果我以 John 身份登录 如何才能只显示 John 的红色按钮而不显示 Susan 的红色按钮 测试系统环境 Win10 Laravel5 4 Mysql5 7 19 table class table table responsive
  • Blade中的Section和Stack有什么区别?

    我们可以使用一个section定义一些 HTML 然后yield那在其他地方 那么为什么我们有堆栈呢 https laravel com docs 5 2 blade stacks https laravel com docs 5 2 bl
  • 如何向 laravel-passport 访问令牌添加自定义声明?

    我刚刚使用了 laravel passport 它与 jwt auth 相同 我想向我的 accessToken 添加一些自定义声明 可以吗 我想通过2fa status gt true在访问令牌和 API 调用时 有了这个访问令牌 我还想
  • 无法显示 Laravel 欢迎页面

    我的服务器位于 DigitalOcean 云上 我正在使用 Ubuntu 和 Apache Web 服务器 我的家用计算机运行的是 Windows 7 我使用 putty 作为终端 遵循所有指示https laracasts com ser
  • octobercms 任务调度不起作用

    我正在使用基于 Laravel 的 OctoberCMS 我没有 SSH 访问我的服务器的权限 每天我需要删除一些注册后 24 小时内未激活帐户的用户 所以我正在考虑使用任务调度 如 cronjobs 根据 10 月 CMSdocs htt

随机推荐

  • 滚动效果:先慢后快

    我正在尝试创建滚动效果 当onclick事件被触发 我想要那个div1滚动到dev2 一开始应该慢 然后快 这是一个使用此效果的网站 http community saucony com kinvara3 http community sa
  • 如何安装和管理多个版本的 R 包

    我正在开发一个使用 R 进行可重现计算的框架 我正在努力解决的一个问题是 某些 R 代码可能在包的 X Y Z 版本中完美运行 但是为什么你在 3 年后尝试重现它 这些包已经更新了 一些功能发生了变化 代码不再运行 此问题还会影响使用包的
  • 为什么2.3版本的android没有android.permission.MODIFY_PHONE_STATE?解决办法是什么? [复制]

    这个问题在这里已经有答案了 可能的重复 如何为 Gingerbread 上运行的应用程序授予 MODIFY PHONE STATE 权限 https stackoverflow com questions 4715250 how to gr
  • 从时间戳获取日期

    我有一个像这样的日期字段 2017 03 22 11 09 55 列名称 install date 我有另一个日期字段 日期如下 2017 04 20 列名称 test date 我只想从上面 2017 03 22 获取日期字段 以便我可以
  • Perl 导入到我的所有包中?

    我倾向于经常使用 Data Dumper 最终我的 pl 代码中每个包的顶部都有以下样板 use strict use warnings use Data Dumper Data Dumper Deparse 1 Data Dumper P
  • Docker 中的 Airflow:如何将 DAG 添加到 Airflow?

    我想将 DAG 文件添加到 Airflow 它在 Ubuntu 上的 Docker 中运行 我用了以下git 存储库 https github com puckel docker airflow 包含配置和 docker 镜像的链接 当我跑
  • 有没有办法使用现有的结构作为枚举变体?

    我使用枚举来实现多态性 类似于以下内容 enum MyType Variant1 a i32 b i32 Variant2 a bool b bool 有没有干净的方法来使用现有的结构Variant1 and Variant2 我做了以下事
  • 使用 dnx/.net core 更改输出程序集和包的名称

    我有一个项目存在于名为Oracle我希望创建的工件被称为MyCompany MyApp Oracle代替Oracle 除了更改目录名称之外 我可以选择哪些选项来更改输出程序集名称和 nuget 包名称 我目前有一个MyCompany MyA
  • 将数据从 MS SQL 导入 MySQL

    我想从 MS SQL Server 导入数据 通过某种正则表达式运行它以过滤掉内容 然后将其导入 MySQL 然后 对于每个查询 我希望显示来自第三个数据库的相关图像 明智地导入和链接 最简单的方法是什么 谢谢 澄清 它是一个 PHP 应用
  • lambda 表达式的 noexcept 和empty throw 规范之间有什么区别吗?

    举个例子 double values 2 5 3 5 4 5 5 5 6 5 7 5 std vector
  • 当 flutter 应用程序终止时,普通推送通知会默默出现或根本不出现

    我在 nodejs 上使用 firebase admin 向用户发送推送通知 https firebase google com docs admin setup https firebase google com docs admin s
  • 向 jQuery .toggle() 方法添加 WAI-ARIA 支持

    我想配对怀阿利亚aria hidden http www w3 org TR wai aria states and properties aria hidden支持 jQuery 的 toggle 方法 所以给出 p Hi there p
  • mPDF 临时文件不可使用 Yii 写入

    我尝试打印 PDF 格式的证书 但是当我将代码推送到暂存阶段时 它说 Temporary files directory var www protected vendor mpdf mpdf src Config tmp is not wr
  • 风暴最大喷口待定

    这是一个关于 Storm 的最大喷口待处理如何工作的问题 我目前有一个 spout 它读取文件并为文件中的每一行发出一个元组 我知道 Storm 不是处理文件的最佳解决方案 但我对此问题没有选择 我设置了topology max spout
  • 监控进程的网络使用情况?

    C 或 C C Win32 中有没有一种方法可以监视某个进程的网络使用情况 显然没有您构建的应用程序 我想只监视 1 个进程大约一个小时左右 然后返回仅该进程 例如 Limewire 使用的字节 是否可以 我知道 Windows 上的 ne
  • NGINX 上的 SSL 终止

    我已经购买了 SSL 证书 并在验证模数时正确地将其捆绑在一起 即https kb wisc edu middleware 4064 https kb wisc edu middleware 4064 那么哈希值是相同的 我已将证书和密钥移
  • Git - 推送到远程存储库中的远程跟踪分支

    当简单地做git push到远程存储库 其master分支得到更新 对于非裸存储库来说 这是不希望出现的情况 最近的 Git 版本显示的警告消息清楚地表明了这一点 我希望能够推送到远程存储库 并拥有其之一远程追踪分支进行更新 稍后 当我登录
  • 每次我尝试将任何内容上传到 android 模拟器时都会出现 IOException

    我使用的是 Windows 7 Ultimate 64 位版本和带有 Android 插件的 Eclipse 3 5 每次我创建一个新项目并尝试发布它时 都会收到如下错误 2010 02 15 22 48 10 EPG3 Uploading
  • Flask 未激活调试模式

    我正在开始使用 Flask 我正在尝试遵循一些教程 但我无法在调试模式下运行 Flask 应用程序 我尝试了我发现的最简单的代码 from flask import Flask app Flask name app debug True I
  • 如何使用 Laravel Mix 和 WorkBox?

    我正在尝试为我的应用程序构建一个 PWA 并花了近 48 小时试图弄清楚如何将 Workbox 与 Laravel Mix 结合使用 具有讽刺意味的是 谷歌说 Workbox 是为了让事情变得简单 Buh 好吧 到目前为止我已经弄清楚了 我