VladimirMikulic / parcel-plugin-custom-dist-structure

🚀 Parcel plugin that allows you to specify a custom dist structure.
https://www.npmjs.com/package/parcel-plugin-custom-dist-structure
MIT License
104 stars 6 forks source link

SCSS Hot Reload fails if options.development: true #9

Closed chuckntaylor closed 4 years ago

chuckntaylor commented 4 years ago

Hi there, after scratching my head for awhile today to figure out why the hot reload was no longer working when I made changes to a scss file, I realized that my problems vanished when I set development to false and not have my folders structured while developing.

The styles do update however, if I save my entry file (index.html) in this case.

I am simply including the scss file in the index.html via tag.

Here are my configurations. Note that in this case, everything works as intended. However, if I change the options.development to true in the package.json file, then SCSS hot reloading no longer works.

package.json

{
  "name": "example",
  "version": "1.0.0",
  "description": "Example",
  "scripts": {
    "start": "parcel ./src/index.html --out-dir build/dev",
    "build": "parcel build ./src/index.html --out-dir build/prod"
  },
  "author": "Chuck Taylor",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@babel/preset-env": "^7.9.5",
    "cssnano": "^4.1.10",
    "parcel-plugin-custom-dist-structure": "^1.1.3",
    "parcel-plugin-nuke-dist": "^1.0.1",
    "sass": "^1.26.3",
    "typescript": "^3.8.3"
  },
  "customDistStructure": {
    "config": {
      "scripts": [
        ".js",
        ".js.map"
      ],
      "styles": [
        ".css",
        ".css.map"
      ],
      "images": [
        ".jpg",
        ".png",
        ".svg"
      ]
    },
    "options": {
      "development": false
    }
  },
  "dependencies": {}
}

.browserslistrc

# Supported Browsers
defaults

.babelrc

{
  "presets": ["@babel/preset-env"]
}

postcss.config.js

module.exports = {
  plugins: [require('autoprefixer'), require('postcss-nested')],
}
VladimirMikulic commented 4 years ago

Hi @chuckntaylor. Thank you for reporting this issue. This is not really the plugin's responsibility (or shouldn't be), but I think that I've managed to fix it. I'll need your help to verify this :)

Please follow the steps:

  1. Clone the project: git clone https://github.com/VladimirMikulic/parcel-plugin-custom-dist-structure.git
  2. Check out the test branch: git checkout fix/hot-reload
  3. Make it available globally on your system: npm link
  4. After running npm link, you'll get the absolute path to the package -> copy it
  5. Enter your project and run npm i -D to install the plugin (before this, make sure to delete the version from NPM)
  6. Report the results here

Thank you.

chuckntaylor commented 4 years ago

Hi @VladimirMikulic

I've gone through the steps you've outlined, which resulted in the following package.json

{
  "name": "chuck_taylor_website",
  "version": "1.0.0",
  "description": "Chuck Taylor Portfolio Website",
  "scripts": {
    "start": "parcel ./src/index.html --out-dir build/dev",
    "build": "parcel build ./src/index.html --out-dir build/prod"
  },
  "author": "Chuck Taylor",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@babel/preset-env": "^7.9.5",
    "@fullhuman/postcss-purgecss": "^2.1.2",
    "cssnano": "^4.1.10",
    "parcel-plugin-custom-dist-structure": "/Users/chuckntaylor/Documents/Sandbox/parcel-plugin-custom-dist-structure",
    "parcel-plugin-nuke-dist": "^1.0.1",
    "sass": "^1.26.3",
    "typescript": "^3.8.3"
  },
  "customDistStructure": {
    "config": {
      "scripts": [
        ".js",
        ".js.map"
      ],
      "styles": [
        ".css",
        ".css.map"
      ],
      "images": [
        ".jpg",
        ".png",
        ".svg"
      ]
    },
    "options": {
      "development": true
    }
  },
  "dependencies": {}
}

However, as before, if I set options.development to true, for whatever reason, when I am editing and saving a linked sass file, the browser fails to refresh. If I make a save on the index page, everything refreshes as normal. I wasn't sure if it had anything to do with how the files relate to each other when the folder structure is made and the css files are placed in the styles folder I defined in the config.

VladimirMikulic commented 4 years ago

Alright, thank you! I'll see what I can do and will inform you soon.

VladimirMikulic commented 4 years ago

Hi @chuckntaylor. I have some good news and bad news for you :)

BAD NEWS HMR is not fixable, because of inner Parcel's workings I can't point the changes to the files that are not in the root of the dist folder.

GOOD NEWS The good news is that page refreshes when you make a change!

It's almost the same as HMR, the only difference is that HMR doesn't do a page reload, instead it replaces the module at runtime. HMR matters the most on bigger projects where it is necessary to make a change but keep the state. (React, Angular...)

Could you please follow the steps again and see if this works for you?

Thank you.

chuckntaylor commented 4 years ago

I won't lie, I don't fully understand everything you just mentioned. 😆 But, yes! Totally works! 🎉 🎉 🎉

VladimirMikulic commented 4 years ago

Awesome :rocket: Thank you for verifying the changes. I'll publish the new release on Thursday, together with #10. Until then you can keep using this approach with an absolute path.

VladimirMikulic commented 4 years ago

v1.1.5 has been released! Check it out.

chuckntaylor commented 4 years ago

Hello @VladimirMikulic,

I just installed the update, and I am seeing the following in the terminal.

Plugin parcel-plugin-custom-dist-structure failed to initialize: Error: Cannot find module 'parcel-bundler/src/HMRServer'
Require stack:
- /Users/chuckntaylor/Documents/PROJECTS/Chuck Taylor Website/frontend/node_modules/parcel-plugin-custom-dist-structure/lib/ind
ex.js
- /Users/chuckntaylor/.config/yarn/global/node_modules/parcel-bundler/src/utils/localRequire.js
- /Users/chuckntaylor/.config/yarn/global/node_modules/parcel-bundler/src/Bundler.js
- /Users/chuckntaylor/.config/yarn/global/node_modules/parcel-bundler/index.js
- /Users/chuckntaylor/.config/yarn/global/node_modules/parcel-bundler/src/cli.js
- /Users/chuckntaylor/.config/yarn/global/node_modules/parcel-bundler/bin/cli.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:982:15)
    at Function.Module._load (internal/modules/cjs/loader.js:864:27)
    at Module.require (internal/modules/cjs/loader.js:1044:19)
    at require (/Users/chuckntaylor/.config/yarn/global/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at Object.<anonymous> (/Users/chuckntaylor/Documents/PROJECTS/Chuck Taylor Website/frontend/node_modules/parcel-plugin-custom-dist-structure/lib/index.js:1:81)
    at Module._compile (/Users/chuckntaylor/.config/yarn/global/node_modules/v8-compile-cache/v8-compile-cache.js:178:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Module.require (internal/modules/cjs/loader.js:1044:19)
VladimirMikulic commented 4 years ago

@chuckntaylor thank you for this information. You have Parcel globally installed, right?

chuckntaylor commented 4 years ago

@VladimirMikulic no problem, Yes, I can call Parcel from anywhere in the terminal. Parcel Version 1.12.4

VladimirMikulic commented 4 years ago

Alright, I've fixed this. It's good that you've encountered this. Now the plugin will look locally first for HMR Server and if it can't find it, it will look for global installation.

Could you please try v1.1.7? Thank you.

chuckntaylor commented 4 years ago

I'm now getting the following:

Plugin parcel-plugin-custom-dist-structure failed to initialize: TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received null
    at validateString (internal/validators.js:117:11)
    at Object.join (path.js:1039:7)
    at Object.<anonymous> (/Users/chuckntaylor/Documents/PROJECTS/Chuck Taylor Website/frontend/node_modules/parcel-plugin-custom-dist-structure/lib/index.js:17:40)
    at Module._compile (/Users/chuckntaylor/.config/yarn/global/node_modules/v8-compile-cache/v8-compile-cache.js:178:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Module.require (internal/modules/cjs/loader.js:1044:19)
    at require (/Users/chuckntaylor/.config/yarn/global/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at localRequire (/Users/chuckntaylor/.config/yarn/global/node_modules/parcel-bundler/src/utils/localRequire.js:11:10)
VladimirMikulic commented 4 years ago

Could you please try putting export NODE_PATH=<absolute_path_to_global_node_modules_folder> in your .bashrc or .zshrc. After you've done this, restart terminal or run source ~/.bashrc/source ~/.zshrc.

Please report the result here. Thank you.

chuckntaylor commented 4 years ago

I believe I have followed your instructions. I am getting the same error though.

I'll just clarify though. I am on Mac 10.15.4 I use Yarn in my projects. I started off putting this line into my .bash_profile

NODE_PATH=/usr/local/lib/node_modules

I believe this is the absolute path to the global node modules. However, I should mention that within that folder I see the following three folders [npm, typescript, yarn].

I started with .bash_profile as I did not have a .bashrc in my home ~ directory. I then created a .bashrc file, which now just has the one line: NODE_PATH=/usr/local/lib/node_modules

I'm suspicious that I don't have that folder quite right because of the 3 folders it contains. For example, when I enter yarn global bin, it points me to /usr/local/bin

VladimirMikulic commented 4 years ago

Could you please try running yarn link parcel-bundler/npm link parcel-bundler in your project's directory to see if the error persists?

chuckntaylor commented 4 years ago

I does unfortunately still persist. While npm link parcel-bundler does what you would expect, I should note that yarn link parcel-bundler results in

error No registered package found called "parcel-bundler".
info Visit https://yarnpkg.com/en/docs/cli/link for documentation about this command.

In both cases though, I did restart terminal before re-launching my app.

chuckntaylor commented 4 years ago

Following the previous comment, I just entered npm unlink parcel-builder and was faced with this error:

npm ERR! code ETARGET
npm ERR! notarget No matching version found for parcel-plugin-custom-dist-structure@1.1.7.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget 
npm ERR! notarget It was specified as a dependency of 'frontend'
npm ERR! notarget 
VladimirMikulic commented 4 years ago

I think that you are doing something wrong. I've tried this on my end and it does solve the problem, link command simply places global parcel-bundler directory in your project's node_modules folder.

Also, I've removed 1.1.7, please install the newest 1.1.9.

chuckntaylor commented 4 years ago

You're probably right. I just tried 1.1.9, but get the same error showing saying that "id" argument needs to be a string, but receiving undefined...

Plugin parcel-plugin-custom-dist-structure failed to initialize: TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received undefined
    at validateString (internal/validators.js:117:11)
    at Module.require (internal/modules/cjs/loader.js:1037:3)
    at require (/Users/chuckntaylor/.config/yarn/global/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at Object.<anonymous> (/Users/chuckntaylor/Documents/PROJECTS/Chuck Taylor Website/frontend/node_modules/parcel-plugin-custom-dist-structure/lib/index.js:8:19)
    at Module._compile (/Users/chuckntaylor/.config/yarn/global/node_modules/v8-compile-cache/v8-compile-cache.js:178:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Module.require (internal/modules/cjs/loader.js:1044:19)
    at require (/Users/chuckntaylor/.config/yarn/global/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
VladimirMikulic commented 4 years ago

@chuckntaylor you are on the right path now. Link global parcel-bundler and you are good to go :)

chuckntaylor commented 4 years ago

I think my issues may be related to this: https://github.com/yarnpkg/yarn/issues/1297

VladimirMikulic commented 4 years ago

It seems that it is related. You can either install parcel-bundler in the project as a dev dependency or reinstall it globally with NPM in order to make the plugin work for you.

chuckntaylor commented 4 years ago

Well.. I have it working finally. :) I can confirm that hot-reloading is working just fine, and the folders are being nicely organized even when options.development is set to true.

I'm not saavy with these symlinks etc (As I'm sure you gathered), but I am guessing this issue is at play as per the yarn issue I linked to previously.

I finally found /Users/chuckntaylor/.config/yarn/global/node_modules/parcel-bundler I navigated there and entered yarn link. This gave the following output:

success Registered "parcel-bundler".
info You can now run `yarn link "parcel-bundler"` in the projects where you want to use this package and it will be used instead.

Then back in my app root folder I entered yarn link parcel-bundler and everything finally clicked.

Thank you for your patience, and your time spent troubleshooting an issue outside the scope of your project.

VladimirMikulic commented 4 years ago

Good work figuring this out. It's a bit weird that in order to link the global module, we have to enter the directory of the global module first and register it. I guess, I learned something new today.

Lastly, thank you for your cooperation and for helping me with testing this tricky issue.