Git Product home page Git Product logo

php-vite-manifest's Introduction

Vite Manifest

A parser for Vite manifest files.

License Version PHP Version Build

Table of contents

Installation

composer require idleberg/vite-manifest

Usage

To get you going, first instantiate the class exposed by this library

new Manifest(string $manifestPath, string $baseUri, string $algorithm = "sha256");

Parameters

$manifestPath

Type: string

Specifies the path to the manifest.

$baseUri

Type: string

Specifies the base URI for the assets in the manifest.

$algorithm

Type: "sha256" |"sha384" |"sha512" | ":manifest:"
Default: "sha256"

Specifies the algorithm used for hashing the assets. This will be used can be used for subsource integrity when printing script or style tags. You can use ":manifest:" in conjunction with vite-plugin-manifest-sri, a plug-in that calculates the hashes at build-time and adds them to the manifest.

Example

use Idleberg\ViteManifest\Manifest;

$baseUrl = "https://idleberg.github.io";
$manifest = "path/to/manifest.json";

$vm = new Manifest($manifest, $baseUrl);

Methods

getManifest()

Usage: getManifest()

Returns the contents of the manifest file as a PHP array

getEntrypoint()

Usage: getEntrypoint(string $entrypoint, bool $hash = true)

Example

$entrypoint = $vm->getEntrypoint("index.ts");

if ($entrypoint) {
    ["url" => $url, "hash" => $hash] = $entrypoint;
    echo "<script type='module' src='$url' crossorigin integrity='$hash'></script>" . PHP_EOL;
}

Returns the entrypoint from the manifest

getImports()

Usage: getImports(string $entrypoint, bool $hash = true)

Returns imports for a file listed in the manifest

Example

foreach ($vm->getImports("index.ts", false) as $import) {
    ["url" => $url] = $import;
    echo "<link rel='modulepreload' href='$url' />" . PHP_EOL;
}

getStyles()

Usage: getStyles(string $entrypoint, bool $hash = true)

Returns stylesheets for a file listed in the manifest

Example

foreach ($vm->getStyles("index.ts") as $style) {
    ["url" => $url, "hash" => $hash] = $style;
    echo "<link rel='stylesheet' href='$url' crossorigin integrity='$hash' />" . PHP_EOL;
}

License

This work is licensed under The MIT License.

php-vite-manifest's People

Contributors

idflood avatar idleberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

haipham idflood

php-vite-manifest's Issues

Css entry not detected as css (css used as input entry)

I'm trying to implement vitejs on my base wordpress theme, and I've found that the css file is injected with a script tag:

$viteAssets->inject(["src/main.js", "src/main.css"], [
  'integrity' => FALSE
]);

The generated manifest.json contains this entry:

"src/main.css": {
    "file": "assets/main-54215d86.css",
    "isEntry": true,
    "src": "src/main.css"
  },

One reason this happen is because the current Manifest.php check for the existence of a css property in the entry which is not the case there. The reason this doesn't have a "css" property is probably because i set the css as an entry input instead of importing it from the javascript.

export const viteConfig = {
  ...
  build: {
  rollupOptions: {
      input: [
          resolve(__dirname, './src/main.js'),
          resolve(__dirname, './src/main.css'),
          resolve(__dirname, './src/editor.css'),
          resolve(__dirname, './src/admin.css')
        ],
      },
  }
  ...
}

So maybe in Manifest.php it should also check if file extension ends with .css to consider the entry as style in addition to the current check.

Manifest file imports are required

Description

Sometimes the manifest.json file doesn't have an includes property, and this throws an error.

This is the line where we are directly accessing includes, which should fail gracefully but instead throws:

}, $this->manifest[$entrypoint]["imports"], [$hash])

Here is my config:

vite.config.ts

export default defineConfig({
  resolve: {
    alias: {
      '~/': `${path.resolve(__dirname, 'src')}/`,
    },
  },
  plugins: [
    // Note, this plugin is the one I made to temporary fix the problem
    manifestImports(),
    liveReload([
      `${__dirname}/*.php`,
      `${__dirname}/includes/**/*.php`,
      `${__dirname}/includes/**/*.mustache`,
    ]),
  ],
  build: {
    outDir: path.resolve(__dirname, './assets/dist'),
    emptyOutDir: true,
    assetsDir: '.',
    manifest: true,
    target: 'modules',
    rollupOptions: {
      // our entry
      input: './assets/src/main.ts',
    },
  },
  server: {
    cors: true,
    strictPort: true,
    port: 5173,
  },
})

manifest.json

{
  "assets/src/main.ts": {
    "file": "main.c291a420.js",
    "src": "assets/src/main.ts",
    "isEntry": true,
    "css": [
      "main.f71924f5.css"
    ],
    "imports": []
  },
  "assets/src/main.css": {
    "file": "main.f71924f5.css",
    "src": "assets/src/main.css",
    "imports": []
  }
}

To fix the problem, I've created this little plugin within the vite.config.ts, but ideally the package would deal with a lack of imports:

vite.config.ts

// Normal config, as above
export default defineConfig({ ...}

// The plugin to add a default imports array
function manifestImports(): Plugin {
  return {
    name: 'vite-plugin-manifest-imports',
    apply: 'build',
    enforce: 'post',
    async writeBundle({ dir }) {
      await augmentManifest('manifest.json', dir!)
    },
  }
}

async function augmentManifest(manifestPath: string, outDir: string) {
  const resolveInOutDir = (path: string) => resolve(outDir, path)
  manifestPath = resolveInOutDir(manifestPath)

  const manifest: Manifest | undefined
    = await fs.readFile(manifestPath, 'utf-8').then(JSON.parse, () => undefined)

  if (manifest) {
    await Promise.all(Object.values(manifest).map(async (chunk) => {
      // adding it here
      if (!chunk.imports) chunk.imports = []
    }))
    await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2))
  }
}

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.