wallabyjs / ngCliWebpackSample

68 stars 48 forks source link

Library project support #32

Closed NickClark closed 6 years ago

NickClark commented 6 years ago

When trying to setup a library project per the directions here: https://github.com/angular/angular-cli/wiki/stories-create-library I'm having a hard time getting wallaby to work. I've tried several different approaches but keep running into various blocks. Could you give us an example of how to set this up?

ArtemGovorov commented 6 years ago

@NickClark Please share a sample repo with wallaby config that you're trying, we are happy to take a look and help with the configuration.

NickClark commented 6 years ago

Thanks... just figured out a workaround.

I put all the wallaby files in the corresponding locations in the sub project and change the corresponding paths. Still didn't work. Turns out I had to change the post processor call to patch the correct nodeModulesDir (which was being set to undefined).

postprocessor: (wallaby) => {
  wallaby.nodeModulesDir = path.resolve('../', '../', 'node_modules');
  return webpackPostprocessor(wallaby);
},

I'll push up an example config in a few minutes.

ArtemGovorov commented 6 years ago

Not sure if the workaround will work, because (for a few reasons) Wallaby config(s) need(s) to be in the project's root folder.

NickClark commented 6 years ago

Here you go. It seems to work. That is effectively the root of that project. It's just that the deps are are installed further up, in the parent (test) app. https://github.com/NickClark/ngCliWebpackSample

ArtemGovorov commented 6 years ago

@NickClark Ah, got it, will check it out. Just to clarify, is everything working for you now (so the issue can be closed)?

NickClark commented 6 years ago

It appears so... although I'd still be interested in some official follow up. 😉

ArtemGovorov commented 6 years ago

@NickClark Just checked and for your case the way you're using is the correct way. It should however be possible to do without setting wallaby.nodeModulesDir, so we have just published wallaby-webpack v3.9.9 and after updating the module, you can this instead of setting wallaby.nodeModulesDir:

...

module.exports = function (wallaby) {

  var webpackPostprocessor = wallabyWebpack({
    ...
    resolve: {
      ...
      modules: [
        path.join(wallaby.projectCacheDir, 'src/app'),
        path.join(wallaby.projectCacheDir, 'src'),
        path.join(wallaby.localProjectDir, '../../node_modules'), // <---
        'node_modules'
      ]
    },
    ...
  });

  return {
    ...

    postprocessor: webpackPostprocessor,
    ...
  };
};
NickClark commented 6 years ago

Thanks!

cdcarson commented 6 years ago

@NickClark did you ever get this working, and, if so, can you share your setup? I tried modifying your ngCliWebpackSample with @ArtemGovorov's fix, but still no luck.

ArtemGovorov commented 6 years ago

@cdcarson The working repo with @NickClark's setup is here https://github.com/NickClark/ngCliWebpackSample

cdcarson commented 6 years ago

@ArtemGovorov Thanks. I couldn't get that working at all. No idea why -- but I've been having pesky npm / Angular CLI troubles.

The good news is that I got a wallaby.js on the root directory to work for both app and a project library, by manually adding entries for the library in various places: entryPatterns, resolve.modules, files and tests. I think this will be OK for me, since I'm pretty sure that I'll only have the one library, and the testing requirements / dependencies don't differ between the two.

In case it helps anyone, here's my working wallaby.js with a library called my-lib...

var wallabyWebpack = require('wallaby-webpack');
var path = require('path');

var compilerOptions = Object.assign(
  require('./tsconfig.json').compilerOptions,
  require('./src/tsconfig.spec.json').compilerOptions);

compilerOptions.module = 'CommonJs';

module.exports = function (wallaby) {

  var webpackPostprocessor = wallabyWebpack({
    entryPatterns: [
      'src/wallabyTest.js',
      'src/**/*spec.js',
       // added...
      'projects/my-lib/src/lib/**/*spec.js'
    ],

    module: {
      rules: [
        {test: /\.css$/, loader: ['raw-loader']},
        {test: /\.html$/, loader: 'raw-loader'},
        {test: /\.ts$/, loader: '@ngtools/webpack', include: /node_modules/, query: {tsConfigPath: 'tsconfig.json'}},
        {test: /\.js$/, loader: 'angular2-template-loader', exclude: /node_modules/},
        {test: /\.json$/, loader: 'json-loader'},
        {test: /\.styl$/, loaders: ['raw-loader', 'stylus-loader']},
        {test: /\.less$/, loaders: ['raw-loader', 'less-loader']},
        {test: /\.scss$|\.sass$/, loaders: ['raw-loader', 'sass-loader']},
        {test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}
      ]
    },

    resolve: {
      extensions: ['.js', '.ts'],
      modules: [
        path.join(wallaby.projectCacheDir, 'src/app'),
        path.join(wallaby.projectCacheDir, 'src'),
        // added...
        path.join(wallaby.projectCacheDir, 'projects/my-lib/src/lib'),
        'node_modules'
      ]
    },
    node: {
      fs: 'empty',
      net: 'empty',
      tls: 'empty',
      dns: 'empty'
    }
  });

  return {
    files: [
      {pattern: 'src/**/*.+(ts|css|less|scss|sass|styl|html|json|svg)', load: false},
      {pattern: 'src/**/*.d.ts', ignore: true},
      {pattern: 'src/**/*spec.ts', ignore: true},
       // added...
      {pattern: 'projects/my-lib/src/lib/**/*.+(ts|css|less|scss|sass|styl|html|json|svg)', load: false},
      {pattern: 'projects/my-lib/src/lib/**/*.d.ts', ignore: true},
      {pattern: 'projects/my-lib/src/lib/**/*spec.ts', ignore: true}
    ],

    tests: [
      {pattern: 'src/**/*spec.ts', load: false},
      {pattern: 'src/**/*e2e-spec.ts', ignore: true},
       // added...
      {pattern: 'projects/my-lib/src/lib/**/*spec.ts', load: false},
      {pattern: 'projects/my-lib/src/lib/**/*e2e-spec.ts', ignore: true}
    ],

    testFramework: 'jasmine',

    compilers: {
      '**/*.ts': wallaby.compilers.typeScript(compilerOptions)
    },

    middleware: function (app, express) {
      var path = require('path');
      app.use('/favicon.ico', express.static(path.join(__dirname, 'src/favicon.ico')));
      app.use('/assets', express.static(path.join(__dirname, 'src/assets')));
    },

    env: {
      kind: 'electron'
    },

    postprocessor: webpackPostprocessor,

    setup: function () {
      window.__moduleBundler.loadTests();
    },

    debug: true
  };
};
ArtemGovorov commented 6 years ago

@cdcarson Thanks for sharing! It is a good way to go, especially if you need to run tests for the app and the library at the same time (if not - you may always split the root config into 2 separate configs, probably with a large reusable chunk in a common file).

dalner commented 5 years ago

Trying to use the @cdcarson's configuration (pretty much exactly) but having an issue where the libraries aren't resolving when I use the direct import (eg import { LibItem } from 'some-lib') The error being Module not found: Error: Can't resolve 'some-lib'..." any thoughts?

ArtemGovorov commented 5 years ago

@dalner Where is the some-lib located relatively to your project's root?

dalner commented 5 years ago

Project structure looks like this:

root:
     - projects
          - some-lib
     - src
          - app
              - file attempting to use 'some-lib'
wallaby.js
ArtemGovorov commented 5 years ago

Thanks, adding the modules root to Webpack resolve.modules should help (so that Webpack uses root/projects as a root when asked to resolve some-lib):

var webpackPostprocessor = wallabyWebpack({
    ...
    resolve: {
      ...
      modules: [
        path.join(wallaby.projectCacheDir, 'src/app'),
        path.join(wallaby.projectCacheDir, 'src'),
        // added...
        path.join(wallaby.projectCacheDir, 'projects/my-lib/src/lib'),
+       path.join(wallaby.projectCacheDir, 'projects'),
        'node_modules'
      ]
    },
    ...
  });
dalner commented 5 years ago

Still seems to have a problem resolving the file. I'm going to tinker with it a bit more tomorrow.

ArtemGovorov commented 5 years ago

Check that the library folder is in the Wallaby files list. Also depending on the lib structure, you may need to add Webpack alias for it in your Wallaby config. If you can provide us with a sample repo demonstrating the issue, we are happy to jump in and help with the config.

dalner commented 5 years ago

Here's a sample of what I'm seeing. https://github.com/GatetotheWest/ngProjectsWallaby

ArtemGovorov commented 5 years ago

@dalner Thanks for providing the repo. I have sent you the pull request with the working config (Webpack alias is required in your case because the library's package.json doesn't give webpack any hints about its entry points).