Giter Site home page Giter Site logo

nystudio107 / craft-plugin-vite Goto Github PK

View Code? Open in Web Editor NEW
12.0 4.0 10.0 177 KB

Plugin Vite is the conduit between Craft CMS plugins and Vite, with manifest.json & HMR support

License: MIT License

PHP 89.72% Dockerfile 0.21% Makefile 1.18% JavaScript 8.89%

craft-plugin-vite's Introduction

craft-plugin-vite's People

Contributors

johndwells avatar khalwat avatar samuelbirch avatar wiejeben avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

craft-plugin-vite's Issues

Inline CSS Loading Fails with Vite 5

Describe the bug

When using Vite 5, the function {{ craft.vite.inline(craft.vite.entry('emails.css')) }} fails to return any output, indicating a significant issue with inline CSS loading. The core of the problem lies within the extractEntry function in manifestHelper.php, which is required to delve deeper due to changes in how CSS files are represented in manifest.json in Vite 5. The malfunction occurs because the styleKey is not correctly retrieved. This is due to the filenameWithoutHash function not functioning correctly, as it only searches for dots in filenames, ignoring dashes. This specific issue traces back to the transition from Vite 3 to Vite 4, where the separator in filenames changed from dots to dashes. However, the repercussions of this change only became apparent with the introduction of Vite 5, due to adjustments in the manifest file structure and the handling of CSS files. A workaround involves modifying line 300 in ManifestHelper.php from $filenameParts = explode('.', $filename); to $filenameParts = preg_split("/[.-]/", $filename);, which addresses the issue and allows the CSS from email.css to be correctly inlined.

To reproduce

To reproduce the behavior, follow these steps:

  1. Upgrade to Vite 5.
  2. Attempt to inline CSS in a Craft CMS template using {{ craft.vite.inline(craft.vite.entry('emails.css')) }}.
  3. Observe that the expected inline CSS is not rendered, indicating the function returns nothing.

Expected behaviour

The expected behavior is for the CSS from emails.css to be correctly inlined when using the {{ craft.vite.inline(craft.vite.entry('emails.css')) }} function in Craft CMS with Vite 5.

Screenshots

N/A

Versions

  • Plugin version: Vite 4.0.8
  • Craft version: Craft 4.7.1

Is `checkDevServer` setting meant for `devServerInternal` setting?

Question

I installed Craft Vite plugin for the first time and set stuff up in my Docker environment. Got it working after a while because I though that to use

{% if craft.vite.devServerRunning() %}
   <base href="{{ alias('@viteBaseUrl') }}">
{% endif %}

checkDevServer setting in config.php file must be set to true.

Because of that I couldn't start my Vite dev server using {{ craft.vite.script("src/ts/main.ts") }}.
Accessing file using hard-coded server link like <script type="module" src="https://localhost:3000/src/ts/main.ts"></script> worked and I though hmm.

Going through your code I found that setting 'checkDevServer' => true causes to proceed further down to ping devServerInternal which in my case is empty string and that makes devServerRunning() function to return false. That caused a cascade of outputs that caused my problem.

So in my dev mode I had my {{ craft.vite.script("src/ts/main.ts") }} twig code that generated script for production and I couldn't get in my browser's console [vite] connected..

My question Andrew is (which seems now quiet obvious) checkDevServer setting meant for devServerInternal setting for example you described in your documentation about using DDEV?

Dev-Server not working with per environment configuration & instant analytics

Describe the bug

Vite build works, but changes with dev-server are not loaded.

My configuration:

return [
    '*' => [
        'useDevServer' => false,
        'manifestPath' => '@webroot/dist/manifest.json',
        'serverPublic' => App::env('SITE_URL') . '/dist/',
        'errorEntry' => 'app.js',
        'cacheKeySuffix' => '',
        'devServerInternal' => '',
        'checkDevServer' => false,
        'includeReactRefreshShim' => false,
        'includeModulePreloadShim' => true,
        'criticalPath' => '@webroot/dist/criticalcss',
        'criticalSuffix' =>'_critical.min.css',
    ],

    'production'  => [
    ],

    'staging'  => [
    ],

    'dev'  => [
        'useDevServer' => true,
        'devServerPublic' => 'http://localhost:3000/',
    ],
];

When I put

  'useDevServer' => true,
  'devServerPublic' => 'http://localhost:3000/',

in the * section, it works.

When I dump the environment in the plugin source code. It shows that Craft CMS is running in dev environment, correctly.

The strange thing is, if I dump dd($this->devServerInternal); in the Vite Plugin the result is
http://craft-instantanalytics-buildchain:3001 (from the also installed instant analytics plugin).

Versions

  • Vite Plugin version: 4.0.5
  • Instant Analytics version: 4.0.2
  • Craft version: 4.3.7.1

No way to combine `craft.vite.asset` with `craft.vite.inline` in Docker

I'm using Docker, where I have a web container and a separate vite container.

{% set logoPath = craft.vite.asset('/src/assets/img/svg/brand-logo.svg') %} returns http://localhost:3000/src/assets/img/svg/brand-logo.svg, which is fine for public use.
But when I want to do this:

{{ craft.vite.inline(logoPath) }}

It fails because we're still in Docker, and it doesn't know localhost:3000 - it needs vite:3000 (the internal dev server url als you call it)

My workaround for now is:

{{ craft.vite.inline(logoPath|replace('localhost', 'vite')) }}

But it would be nice to have an option for example on craft.vite.asset to use the internal dev server url

on demand loading of external files

Hi,

I'm trying to get a setup where i can use the craft.vite.register to only load in an external file (library) when needed, on the whole this is working ok(ish) but i'm running into a few issues i'm hoping you can help with.

In the vite.config.js file i have this in the build options:
rollupOptions: { input: { app: root+'/src/js/app.js', htmx: 'htmx.org', splide: '@splidejs/splide', }, }

now in a twig partial i add this {{ craft.vite.register("node_modules/htmx.org/dist/htmx.min.js") }} and it works fine both with the devServer and in production.

First question: I haven't been able to figure out how or if possible to modify the key in the the manifest file to use the value from the rollupOptions above instead of using the full location. So ideally i'll like to use {{ craft.vite.register("htmx.org") }} - if this is not possible to do via vitejs options is it possible to tweak this plugin to allow for partial matches on the manifest keys?

This also leads onto another issue. When referencing the Splide lib: {{ craft.vite.register("node_modules/@splidejs/splide/dist/js/splide.js") }} this works on the devServer, but not in production. When built the manifest uses the esm version and therefore this full location it not in the manifest file. - This would be solved with the ability to use partial matches.

Second question: When I update the location to match the one in the manifest file to test it out. The file loads (apparently) but the global object which the lib is providing (Splide) which works in the devServer is not to be found in production. - I know this nothing to do with this plugin, but i hoping you may have come across this issue before and know how to resolved it?

Thanks

Vite Plugin and frontend templates w template hooks

I'm currently using Template Hooks to serve frontend templates from my plugin. I was wondering if it is still possible to use Vite with this setup?

To test, I downloaded your transcoder plugin and added in a template hook. However, I can only get the HMR to work if I keep the /transcoder/welcome page open in a seperate tab.

getCssHash() returns incorrect value

Describe the bug

As of 4.0.7, getCssHash() is incorrectly removing a section of the hash if it includes a dash. For instance, this hash is being reported as rmXHq:

"asset-src/build/main-preload.js": {
    "css": [
      "main-preload.G7-rmXHq.css"
    ],
...

This is appears to be related to changes made for #21. Reverting to 4.0.6 resolves the issue.

Versions

  • Plugin version: 4.0.7
  • Craft version:4.7.0

Cache busting with [hash] as queryparameter instead of filename

Hi Andrew!
We use the craft.vite.script() function to create tags automagically, but we now walk into something of a feature request.
We're building the assets without hash, but we want to make use of the hash that's in manifest as a cache-busting mechanism.

I know I could place all the script/links tags manually in the layout and paste ?v={{ craft.vite.getCssHash("src/js/app.ts") }} behind every url.
But it would be awesome to have if we can do this as an extra parameter in the .script() function like below and keep the awesomeness that .script() is generating:

{{ craft.vite.script("src/js/app.ts", true,{},{},{
queryparams: 'v='~craft.vite.getCssHash("src/js/app.ts")
}) }}

What do you think of this?

Cheers!

craft.vite.getCssHash no longer working as expected

Describe the bug

The default format for files outputted by Vite/Rollup is now [name]-[hash].[extension] rather than [name].[hash].[extension].

This means that the {{ craft.vite.getCssHash() }} function no longer works as intended, because it's looking for the first . in the filename and not finding one, which means the hash that's returned is malformed because the offset passed to substr on line 110 of Services/Helper.php is always 1.

For example, a CSS file output from Vite might look like this:

main-PF0JF2pS.css

Calling {{ craft.vite.getCssHash('main-PF0JF2pS.css') }} will currently return the following:

ain-PF0JF2pS

Expected behaviour

In the example above, the expected output from {{ craft.vite.getCssHash('main-PF0JF2pS.css') }} would be:

PF0JF2pS

Versions

  • Plugin version: 4.0.6
  • Craft version: 4.5.11.1
  • Vite version: 5.0.6

Auto reload not happening on twig template changes

I've setup a local environment and everything is working as expected except that auto reloading isn't happening whenever twig files are modified. CSS and Javascript files are all loaded with HMR as expected so this is only browser reload. The vite.config.js was pulled straight from your repo (link below).

https://github.com/nystudio107/craft/blob/craft-vite/buildchain/vite.config.js

I've attempted to modify the settings passed into VitePlugin, but haven't been able to get it to work.

Any ideas on what I could start looking at to find the issue?

Versions

  • Plugin version:1.0.17
  • Craft version:3.6.4

Asset URL generation causing DB writes on the front-end

I was not sure where exactly to report this as I noticed it coming via Retour & SEOMatic, but the common element is the Vite plugin, so here we are!

The bug

On the front-end of a site I have I am seeing DB writes like this:

INSERT INTO `resourcepaths` (`hash`, `path`) VALUES ('7facf4f9', '@nystudio107/retour/web/assets/dist') ON DUPLICATE KEY UPDATE `path`=VALUES(`path`)
INSERT INTO `resourcepaths` (`hash`, `path`) VALUES ('8dc133d6', '@nystudio107/seomatic/web/assets/dist') ON DUPLICATE KEY UPDATE `path`=VALUES(`path`)

Going up the stack, VitePluginService::init() is the common element, specifically, here:

$baseAssetsUrl = Craft::$app->assetManager->getPublishedUrl(

This will eventually trigger the DB writes.

Background

The "why" for this is that I am trying to reduce the number of DB writes on the front-end of our sites, as due to the fix for this craftcms/cms#12557 long-ish running db backups can block the front-end if there are writes during the backup.

To reproduce

  1. On a site using SEOMatic or Retour (probably others that use the Vite plugin too)
  2. Enable Debug toolbar
  3. Load a front-end URL
  4. Notice DB write queries on every request

Expected behaviour

Some mechanism to prevent the Vite plugin asking Craft for a published asset URL when no Vite plugin functionality is used on the front-end of a site. This could be a setting, config variable or potentially moving the relevant code out of VitePluginService::init().

Versions

  • Plugin version: 4.0.10
  • Craft version: 4.8.9

Upgrade to Craft 4 + vite plugin update breaks reload of twig files

Describe the bug

In the vite.config.js I have the vite-plugin-restart plugin installed with the following config:

ViteRestart({
    reload: [
        path.join(__dirname, './templates/**/*'),
    ],
}),

Previously this worked like a charm but after updating everything to Craft 4 including the vite plugin for Craft this stopped working. The HMR for CSS & JS files are working fine though. Normally you get a notification in the terminal on save saying:

11:18:34 AM [vite] page reload templates/index.twig

It is now empty or after multiple saves the number of times you saved but doing no reload

11:18:34 AM [vite] 
11:18:34 AM [vite] (x2)

sidenote: I'm also noting that after saving the vite.config.js file i'm getting the error:

client.ts:203          GET http://siteurl.nitro/__vite_ping 404 (Not Found)

To reproduce

  1. nitro ssh
  2. npm run dev
  3. save a twig file from the templates folder

Expected behaviour

After hitting save in a .twig file reloading the browser

Versions

  • Plugin version: 4.0.0-beta.4
  • Craft version: Craft Pro 4.0.1
  • PHP version: 8.0.17

Would love to natively remove site styles on error entries!

Is your feature request related to a problem? Please describe.

Not necessarily! When you set error entry to your main.js, and your js file includes site styles, these override the Craftcms error log styles. For a while I (dumbly) thought it was a craft dark mode update or something lol, but it made the error logs very hard to read.

Describe the solution you would like

I would love if the plugin could detect a 500 error and not include the style tag, or remove it natively.

Describe alternatives you have considered

I have a homemade solution in my js, but it's not ideal, as things could change with craft and plugin updates, and I am making assumptions. Here is the code though.

    // when we run into twig errors, the site styles make it impossible to read.
    // the error entry has no class on the body, and our layout always does, so this
    // is a way to check if we are in an error entry.
    // we use the title as a fallback, as well as the domain because we REALLY
    // do not want this to happen on production
    ;(function removeStylesOnDevErrorEntry() {
        if (
            !document.querySelector('body').hasAttribute('class') &&
            document.title.toLowerCase().includes('error') &&
            domain.includes('test')
        ) {
            const myStyles = document.querySelector('style[data-vite-dev-id]')
              if(myStyles) {myStyles.remove()}
        }
    })()

Additional context

Without my removal :

Screen Shot 2023-06-11 at 11 07 28 AM

Add support for Servd Bundle Hash

Is your feature request related to a problem? Please describe.

The problem is that my site's caching (Servd & Cloudflare) creates a situation where the available css & js assets differ from the cached version of the manifest.json file. This renders the site without styles applied for a moment after deployment.

Servd's suggested approach to cache-busting assets is to append the SERVD_BUNDLE_HASH to the end of the asset file urls. I'd like to be able to accomplish this as it's described in their docs: https://servd.host/docs/cache-busting#using-the-bundle-hash

Describe the solution you would like

Provide a config option to append a string like ?v={{ getenv('SERVD_BUNDLE_HASH') }} to the end of the compiled assets on build.

Using rollupOptions.output in my vite.config file, I'm able to remove the Vite hash from the file name, which renders this in my site head:

<link href="https://my.ddev.site/dist/assets/app.css" rel="stylesheet">

My request is to append a string to the end of the href like so (assuming the SERVD_BUNDLE_HASH is "123456"):

<link href="https://my.ddev.site/dist/assets/app.css?v=123456" rel="stylesheet">

Describe alternatives you have considered

I've been blowing up the servd team ( @mattgrayisok & Joe ) on their intercom about configuring for Vite. The above article has 2 suggestions that would be problematic:

  1. Clear site cache on post-deploy: this would put a large load on our server every time i push code to production as Servd would be forced to re-cache the whole site
  2. Include historical copies of my assets: I don't think this is possible with Vite as the entire dist folder is wiped out on build
  3. In my vite.config.js, I removed the hash with the rollupOptions.output config:
build: {
        [...]
        rollupOptions: {
            [...]
            output: {
                assetFileNames: `assets/[name].[ext]`,
                entryFileNames: `assets/[name].js`,
            },
        },
    },

Then using Ben C's (@bencroker) cloudflare plugin, I'm attempting to purge the cache when the bundle is built, with the cloudflare/purge/purge-urls console command. Unfortunately, this is also not purging the css & js files as expected after a build.

Additional context

This Vite local setup absolutely rules and I'm committed to making it work somehow. I'm certainly open to other solutions if you have thoughts. Just looking to avoid the site rendering without styles & scripts.

Consistent use of "useDevServer"

Describe the bug

The plugin uses two "DEV_MODE" & "VITE_PLUGIN_DEVSERVER" env variables.
And not there values but juste the presence of the variable

Expected behaviour

It should only take "useDevServer" in config/vite.php

Versions

  • Plugin version: 1.0.3
  • Craft version: 3.6.12

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.