Urigo / meteor-client-bundler

https://blog.meteor.com/leverage-the-power-of-meteor-with-any-client-side-framework-bfb909141008
MIT License
192 stars 41 forks source link

Bundling Issues with "ionic build browser --prod" Module not found: Error: Can't resolve 'meteor/jalik:ufs' #44

Closed ansaries closed 6 years ago

ansaries commented 7 years ago

import { UploadFS } from 'meteor/jalik:ufs'; // works in dev mode.

following is my config.json:

{
    "runtime": {
        "DDP_DEFAULT_CONNECTION_URL": "https://foctest.meteorapp.com",
        "ROOT_URL": "https://foctest.meteorapp.com",
        "MOBILE_URL": "https://foctest.meteorapp.com"
    },
    "import": [
        "accounts-base",
        "accounts-password@1.3.6",
        "tmeasday:publish-counts",
        "ground:db@2.0.0-rc.7",
        "alanning:roles",
        "check@1.2.5",
        "tmeasday:presence",
        "mys:accounts-phone",
        "jalik:ufs@0.7.1_1",
        "jalik:ufs-gridfs@0.1.4"
    ]
}

The application runs perfectly well in development mode, on a browser and even on devices, in fact, I have managed to deploy a dev build on https://fixonclick-1384.firebaseapp.com which is also running well. But when I build using --prod the build process breaks with the Module not found message. May be it's because the meteor package resolver is in externals of webpack config as mentioned in #38 .

My web app is running separately and built using Meteor cli and hosted on galaxy with meteor server. Where as I have built a prototype of Ionic PWA(for the mobile browser users) and APK using meteor-client bundler and connecting with the server using above config.

p.s: My Ionic App Project is completely separate from my Meteor Project. Do I need to put the meteor project inside of the api/server to get the dependencies from the api/server as mentioned in the webconfig resolve alias.

ansaries commented 7 years ago
const UploadFS = Package['jalik:ufs'].UploadFS; 
const Mongo = Package['mongo'].Mongo; 

seems to be the only solution for now.

ansaries commented 7 years ago

https://github.com/ionic-team/ionic-app-scripts/issues/954

ansaries commented 7 years ago

Ok so we have to make two webpack.config.js one for dev and one for build --prod.

Steps to fix the issue: in package.json include following:

"config": {
    "ionic_sass": "./config/sass.config.js",
    "ionic_webpack": "./config/dev.config.js",
    "ionic_optimization": "./config/prod.config.js"
  },

Following is my dev.config.js

var path = require('path');
var webpack = require('webpack');
var ionicWebpackFactory = require(process.env.IONIC_WEBPACK_FACTORY);
var ModuleConcatPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');

var prodPlugins = [];
if (process.env.IONIC_ENV === 'prod') {
    prodPlugins.push(new ModuleConcatPlugin());
}
module.exports = {
    entry: process.env.IONIC_APP_ENTRY_POINT,
    output: {
        path: '{{BUILD}}',
        publicPath: 'build/',
        filename: '[name].js',
        devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
    },
    devtool: process.env.IONIC_SOURCE_MAP_TYPE,

    resolve: {
        extensions: ['.ts', '.js', '.json'],
        modules: [path.resolve('node_modules')],
        alias: {
            'api': path.resolve(__dirname, '../src/api')
        }

    },
    externals: resolveExternals,
    module: {
        loaders: [
            {
                test: /\.json$/,
                loader: 'json-loader'
            },
            {
                test: /\.ts$/,
                loader: process.env.IONIC_WEBPACK_LOADER
            },
            {
                test: /\.js$/,
                loader: process.env.IONIC_WEBPACK_TRANSPILE_LOADER
            }
        ]
    },

    plugins: [
        ionicWebpackFactory.getIonicEnvironmentPlugin(),
        ionicWebpackFactory.getCommonChunksPlugin(),
    ].concat(prodPlugins),

    // Some libraries import Node modules but don't use them in the browser.
    // Tell Webpack to provide empty mocks for them so importing them works.
    node: {
        fs: 'empty',
        net: 'empty',
        tls: 'empty',
        __dirname: true
    }
};
function resolveExternals(context, request, callback) {
    return resolveMeteor(request, callback) ||
        callback();
}

function resolveMeteor(request, callback) {
    var match = request.match(/^meteor\/(.+)$/);
    var pack = match && match[1];
    if (pack) {
        console.log('Dev:', pack); // this one shows in development only.
        callback(null, 'Package["' + pack + '"]');
        return true;
    }
}

and my build.config

var path = require('path');
var useDefaultConfig = require('@ionic/app-scripts/config/optimization.config.js');

module.exports = function () {
    useDefaultConfig.node = {
        fs: 'empty',
        net: 'empty',
        tls: 'empty',
        __dirname: true
    };
    useDefaultConfig.resolve.alias = {
        'api': path.resolve(__dirname, '../src/api')
    };
    useDefaultConfig.externals = resolveExternals;
    return useDefaultConfig;
};

function resolveExternals(context, request, callback) {
    return resolveMeteor(request, callback) ||
        callback();
}

function resolveMeteor(request, callback) {
    var match = request.match(/^meteor\/(.+)$/);
    var pack = match && match[1];
    if (pack) {
        console.log(pack); // this one shows during build optimization step.
        callback(null, 'Package["' + pack + '"]');
        return true;
    }
}
ardatan commented 6 years ago

You can just use generateNodeModules option in meteor-client-bundler configuration.