Repository: opencomponents/oc (js)

Issue:
react-app-polyfill cannot be added as dependency
## *Who* is the bug affecting?
Anyone trying to package an open component with the dependency `react-app-polyfill`

## *What* is affected by this bug?
The client, with any template (I've tried with handlebars and react templates).

## *When* does this occur?
When you try to package or run a dev server, packaging fails with a `FAIL` (no more errors).

## *Where* on the platform does it happen?
It's something with dependencies management, on the CLI.

## *How* do we replicate the issue?
1. Install oc globally: `npm i -g oc`
2. Create a new repo with the react template: `oc init my-awesome-repo oc-template-react`
3. Inside the repo, add the package `react-app-polyfill` as dependency: `npm add --save react-app-polyfill`
4. Go outside the repo and try to init a dev server, or simply to package the project: `oc dev . 3030`

![imatge](https://user-images.githubusercontent.com/153305/48358972-3dbec800-e69c-11e8-8d54-37c7de8dd4b3.png)

## Expected behavior (i.e. solution)
App should build or, at least, show a more specific error (right now just fails with a `FAIL` and nothing else, even if verbosity is enabled).

## What version of OC, Node.js and OS are you using?
- OC: From 0.43.1 to current version (0.45.0)
- NodeJS: From 6 to 8
- OS: Ubuntu Linux

Pull request description:
Fix handling of missing dependencies
The issue was that for some packages, there is not an entry point
defined in the package.json, so trying to require the module is not an
effective way to determine if the package is installed, so we try to
also require the package.json from that library to make the check more
robust.

Closes #964 

Patch:
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..949f59b8
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,8 @@
+{
+  "trailingComma": "none",
+  "tabWidth": 2,
+  "semi": true,
+  "singleQuote": true,
+  "useTabs": false,
+  "arrowParens": "always"
+}
diff --git a/src/cli/domain/handle-dependencies/get-missing-dependencies.js b/src/cli/domain/handle-dependencies/get-missing-dependencies.js
index c9453ce6..9cf65858 100644
--- a/src/cli/domain/handle-dependencies/get-missing-dependencies.js
+++ b/src/cli/domain/handle-dependencies/get-missing-dependencies.js
@@ -3,13 +3,13 @@
 const path = require('path');
 const _ = require('lodash');
 
-const cleanRequire = require('../../../utils/clean-require');
+const moduleExists = require('../../../utils/module-exists');
 
-module.exports = dependencies => {
+module.exports = (dependencies) => {
   const missing = [];
   _.each(dependencies, (version, dependency) => {
     const pathToModule = path.resolve('node_modules/', dependency);
-    if (!cleanRequire(pathToModule, { justTry: true, resolve: true })) {
+    if (!moduleExists(pathToModule)) {
       missing.push(`${dependency}@${version || 'latest'}`);
     }
   });
diff --git a/src/utils/module-exists.js b/src/utils/module-exists.js
new file mode 100644
index 00000000..fa47afba
--- /dev/null
+++ b/src/utils/module-exists.js
@@ -0,0 +1,16 @@
+'use strict';
+
+const tryRequire = require('try-require');
+const path = require('path');
+
+module.exports = (moduleName) => {
+  const packageModulePath = path.join(moduleName, 'package.json');
+
+  if (require.cache && !!require.cache[packageModulePath]) {
+    delete require.cache[packageModulePath];
+  }
+
+  return (
+    !!tryRequire.resolve(moduleName) || !!tryRequire.resolve(packageModulePath)
+  );
+};


Test patch:
diff --git a/test/unit/cli-domain-handle-dependencies-get-missing-dependencies.js b/test/unit/cli-domain-handle-dependencies-get-missing-dependencies.js
index 2196aeb5..21730dc1 100644
--- a/test/unit/cli-domain-handle-dependencies-get-missing-dependencies.js
+++ b/test/unit/cli-domain-handle-dependencies-get-missing-dependencies.js
@@ -24,19 +24,19 @@ describe('cli : domain : handle-dependencies - get-missing-dependencies', () =>
     }
   ];
 
-  scenarios.forEach(scenario => {
+  scenarios.forEach((scenario) => {
     const { dependencies, installed, output } = scenario;
     describe(`When dependencies: ${JSON.stringify(
       dependencies
     )} and installed: ${JSON.stringify(installed)}`, () => {
       const pathResolveSpy = sinon.spy();
-      const cleanRequireSpy = sinon.spy();
+      const moduleExistsSpy = sinon.spy();
       const getMissingDependencies = injectr(
         '../../src/cli/domain/handle-dependencies/get-missing-dependencies.js',
         {
-          '../../../utils/clean-require': (name, options) => {
-            cleanRequireSpy(name, options);
-            return installed[name] ? { dependency: true } : undefined;
+          '../../../utils/module-exists': (name) => {
+            moduleExistsSpy(name);
+            return installed[name];
           },
           path: {
             resolve: (...args) => {
@@ -56,12 +56,8 @@ describe('cli : domain : handle-dependencies - get-missing-dependencies', () =>
           expect(pathResolveCall[0]).to.equal('node_modules/');
           expect(pathResolveCall[1]).to.equal(_.keys(dependencies)[i]);
         });
-        cleanRequireSpy.args.forEach((cleanRequireCall, i) => {
-          expect(cleanRequireCall[0]).to.equal(_.keys(dependencies)[i]);
-          expect(cleanRequireCall[1]).to.eql({
-            justTry: true,
-            resolve: true
-          });
+        moduleExistsSpy.args.forEach((moduleExistsCall, i) => {
+          expect(moduleExistsCall[0]).to.equal(_.keys(dependencies)[i]);
         });
       });
     });