jedwards1211 / meteor-imports-webpack-plugin

Webpack plugin to import and use Meteor packages like if they were real NPM packages.
MIT License
25 stars 10 forks source link

Error: Run Meteor at least once. #25

Open dobesv opened 6 years ago

dobesv commented 6 years ago

Although I have run meteor many times, there's no folder .meteor/local/build. Is this something they have changed about meteor, or is there a specific command that would create and populate that folder?

If I run meteor build --directory .meteor/local/build/programs it creates what may be the expected files in .meteor/local/build/programs/bundle/programs/web.browser, which still does quite seem to match the expected directory structure in the instructions in here.

DylanLyon commented 6 years ago

@dobesv I'm having the same issue, which is weird because it was working fine up until it wasn't! Any luck figuring it out?

dobesv commented 6 years ago

No, I don't think I ever got this to work. For storybook we're just using some plugin that redirects imports to stubs we create specifically for storybook to use.

DylanLyon commented 6 years ago

Could you expand a little on your stubs workaround, or possibly point me in the proper direction? I've been trying to get Storybook/Styleguidist working with our project for over a week now and haven't had any luck.

Ultimately, I was going to just use react-docgen directly through the CLI to spit out JSON for each component's JSDocs that I could then figure out a way to import into Storybook/Styleguidist after the fact.

dobesv commented 6 years ago
$ cat .storybook/webpack.config.js 
const path = require('path');

const stubs = [
  'graphql-redis-subscriptions',
  'bunyan',
  'mongodb',
  'meteor/meteor',
  'meteor/kadira:flow-router',
  'meteor/mongo',
  'meteor/random',
  'meteor/tracker',
  'meteor/jquery',
  'meteor/mdg:validated-method',
  'meteor/aldeed:simple-schema',
  'meteor/accounts-base',
  'meteor/ddp-rate-limiter',
  'meteor/dburles:factory',
];

/* eslint-disable no-param-reassign */
module.exports = sbConfig => {
  if (!sbConfig.resolve.alias) sbConfig.resolve.alias = {};

  stubs.forEach(module => {
    sbConfig.resolve.alias[module] = path.resolve(
      __dirname,
      `../etc/testing/mocks/${module.replace(':', '_')}.js`,
    );
  });

  sbConfig.resolve.alias['/imports/ui/client/calculator.js'] = path.resolve(
    __dirname,
    `../etc/testing/mocks/calculator.js`,
  );

  sbConfig.module.rules.push({
    test: /\.(scss|css)$/,
    loaders: ['style-loader', 'css-loader', 'sass-loader'],
    include: path.resolve(__dirname, '../'),
  });

  sbConfig.module.rules.push({
    test: /\.(graphql|gql)$/,
    exclude: /node_modules/,
    loaders: ['graphql-tag/loader'],
  });

  sbConfig.module.rules.push({
    test: /\.(ttf|eot|woff|woff2)$/,
    loader: 'file-loader',
    options: {
      name: 'fonts/[name].[ext]',
    },
  });

  sbConfig.node = {
    bindings: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
  };

  return sbConfig;
};
$ cat .storybook/.babelrc 
{
  "plugins": [
    "module:babel-root-slash-import",
    [
      "module-resolver",
      {
        "root": [
          "./imports"
        ],
        "alias": {
          "api": "./imports/api"
        }
      }
    ]
  ],
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "browsers": [
            "last 2 Chrome versions"
          ]
        }
      }
    ],
    "@babel/preset-stage-0",
    "@babel/react"
  ]
}
dobesv commented 6 years ago
$ cat etc/testing/mocks/meteor/meteor.js 
import settings from '/settings-development.json';

export const mockUser = {
  _id: '1',
  profile: { firstName: 'Lenny', lastName: 'Kravitz' },
  hasToggle: () => true,
  isTeacher: () => true,
  isStudent: () => false,
};

export const Meteor = {
  isClient: true,
  isStorybook: true,
  isServer: false,
  settings,
  user: () => mockUser,
  userId: () => mockUser._id,
};
dobesv commented 6 years ago

Hopefully that gives the gist of it. We have some other mocks we've made for FlowRouter, etc., which have pretty simple no-op implementations along the same lines.

jedwards1211 commented 6 years ago

It may be possible to get things working with storybook or styleguidist, but it may be tricky. I would recommend writing dumb components that don't depend on any core Meteor modules, and working on the appearance of those components in styleguidist, then writing separate components to wrap the dumb components with data pulled in from Meteor.

At the very least you'll need to somehow inject a __meteor_runtime_config__ variable into the browser to make things work with this plugin (see https://github.com/jcoreio/crater/blob/master/src/server/createSSR.js for an example).

CaptainN commented 4 years ago

I ran in to the same problem. I'm pretty sure it had worked, but then it stopped. The difference seems to be in the what context is sent to the getMeteorBuild resolve function. It was sending the full project URL with app appended, instead of passing the root of the project.

I supposed that means we can work around it 2 ways: 1. Move the meteor project within app, or 2. Set the meteorProgramsFolder config option thusly: meteorProgramsFolder: '../web/.meteor/local/build/programs'

The latter is what I did. If it fails again due to the path root changing again, a quick edit and I'm off and running again.