简体   繁体   中英

How to link something from manifest.json

I'm using Webpack with the CleanWebpackPlugin, but I use an index.php. So HtmlWebpackPlugin isn't an option. I found a different plugin called WebpackManifestPlugin. This creates a file with the files and their hash called manifest.json. It looks like this:

{ "main.js": "css.d915ef.js", "main.css": "main.d915ef.css" }

But how do I use this in my head?

<link rel="stylesheet" type="text/css" href="dist/main.css">

Because this doesn't work.

Use that function in php script

function asset($asset_name)
{
    $manifest = file_get_contents("./manifest.json");
    $manifest = json_decode($manifest, true); //decode json string to php associative array
    if (!isset($manifest[$asset_name])) return $asset_name; //if manifest.json doesn't contain $asset_name then return $asset_name itself
    return "/dist/" . $manifest[$asset_name];
}

It will read and parse manifest.json and replace "main.js" with "css.d915ef.js" You can use asset() function while generating yout html, like this:

<link rel="stylesheet" type="text/css" href="<?php echo asset("main.js"); ?>">

Please, be aware, that file_get_contents("./manifest.json") will only work correctly if your php script and manifest.json is in the same folder. If not - you need to provide correct path to manifest.json here.

Another option is to disable hash inserting via webpack.config.js file.

You need to find all [hash] occurence and remove it from webpack.config.js . Then use npm run to recompile everything.

For example, you have

output: {
           path: path.resolve(__dirname, './public/'),
           filename: '[name].[hash].js'
        }

Replace it with:

output: {
           path: path.resolve(__dirname, './public/'),
           filename: '[name].js'
        }

I have a similar situation with Create React App and a PHP file.

The Create React App configuration creates an asset-manifest.json file in which all the files that are needed in the page are listed under the entrypoints key.

"entrypoints": [
  "static/js/runtime-main.bff00530.js",
  "static/js/2.8bab6741.chunk.js",
  "static/css/main.262e5e5f.chunk.css",
  "static/js/main.e2f4dbf8.chunk.js"
]

In my code I'm doing the following (expanding on @krylov123 's answer ):

// get the original values
$manifest = file_get_contents("./asset-manifest.json");
$manifest_values = json_decode($manifest, true);
$entrypoints = $manifest_values['entrypoints'];

Then I'm creating two separate arrays: one for the css and another for the js files. In order to do so I've created an helper function filterPaths (you may create your own):

// return only paths continaint a specific string
function filterPaths($paths, $value): array {
  return array_filter($paths, function ($filename) use ($value): bool {
    return strpos($filename, $value) !== false;
  });
}

Here I create the two arrays:

// filter '.css' files
$css_files = filterPaths($entrypoints, '/css/');
// filter '.js' files
$js_files = filterPaths($entrypoints, '/js/');

Then in the html part I loop over the two arrays in order to print link tags for CSS and script tags for JavaScript.

This is the syntax using blade, but you can adapt it to normal php:

@foreach($css_files as $link)
  <link href="{{ $link }}" rel="stylesheet">
@endforeach
@foreach($js_files as $link)
  <script src="{{ $link }}"></script>
@endforeach

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM