0

I have a javascript file that isn't part of my project but that needs to be bundled up with it when it is served. This file has contents basically in the form...

FT.manifest({
   "foo": "bar",
   "id": 3
})

...where the Object part is well formed JSON.

I have webpack set up and am using the copy-webpack-plugin to move this file to my ./dist folder along with all my bundled JS and other assets.
Nothing fancy, just a straight file to file copy...

new CopyWebpackPlugin({
   patterns: [
      {from:`./src/templates/${dirName}/manifest.js`, to: `${dirName}/manifest.js`},
   ]
})

This works fine when I run webpack in development mode and the copied file looks exactly the same as the original but when I run in production mode the content get inlined and loses the speech marks from around the keys in the Object portion. The output now looks like this...

FT.manifest({foo:"bar",id:3})

Notice the lack of speech marks on foo and id. There is obviously some optimisation happening when --mode=production that is removing the line breaks and other formatting (which is fine) but it is also stripping the speech marks out and this causes problems for some steps that happen down the line.

So, can you tell my why this might be happening what I can do stop this particular file from being optimised during the copying process.
I can't do anything about the format of the particular file as it is from a third party but I can use other plugins or change the process at my end if needed.

Thanks for your help

popClingwrap
  • 3,919
  • 5
  • 26
  • 44
  • `{ "foo": "bar","id": 3}` and `{ foo: "bar",id: 3}` are exactly the same thing for JS. the second one shaves off 4 characters, that's it. – Jeremy Thille Feb 24 '21 at 16:57
  • But later on there is a step that uses fs.readfile to read in the file, strip the Object portion and run it through JSON.parse(). This throws an error when it comes to the un-speechmarked keys. – popClingwrap Feb 24 '21 at 17:38
  • @JeremyThille, yes - for JavaScript they are same and also not. 1st it real JSON, second is JavaScript object so NO THEY ARE NOT THE SAME. You will get 2nd from parsing 1st as JSON, and you will got 1st when stringifying 2nd - but they are - but they would never be the same (for example JSON do not support `undefined` values (it just drops them) – Seti Feb 24 '21 at 18:52
  • I never said THEY ARE THE SAME. I said "They are the same for JS". Take a JSON, remove the quotes around the keys, and JS will treat it _exactly_ the same way. – Jeremy Thille Feb 25 '21 at 06:24
  • I think the question is valid(ish) in that I would like to be able to exclude certain files from the 'production' process and simply copy them unchanged. I'm coming round to the fact that I was probably achieving my results in a clumsy way though by trying to hack valid JSON from a JS string. I have found a solution that works which I'll detail in an answer just in case anyone else cares. – popClingwrap Feb 25 '21 at 11:37

1 Answers1

0

I think the question of how to exclude certain files from the 'production' optimisation processes is a valid one but I've come round to the idea that my specific problem was more to do with my clumsy solution than anything else. I have found a way to do this that is quicker and more elegant.

What I was doing was to use copy-webpack-plugin to move the files from my ./src to my ./dist and then read them and manipulate them in place after they were emitted which adds a whole set of file system actions as well as requiring the js file to be read as a string and the Object portion to be pulled out and converted to JSON (which fails after the file has been optimised and the speech marks stripped out).

What I have learned is that the copy-webpack-plugin itself allows you to perform transformations on the file data as it is being copied. This means you get the data as it is in the original and can do away with the whole process of then re-reading and transforming the final emitted file.

{
   from:`./src/${dirName}/myFile.js`,
   to: `${dirName}/myFile.js`,
   transform:{
      transformer(content, absolutePath){
         let str = content.toString();
         // Make changes to str here and return the amended data
         return str;
      }
   }
}

This is all there in the plugin docs so probably isn't new to most people but I didn't know you could do this. Maybe someone else will find it useful.

popClingwrap
  • 3,919
  • 5
  • 26
  • 44