Installing an npm package and using it in TSX files

1

This is my first React/Typescript/ASP.NET Core app, so please forgive my ignorance. I am trying to install a new module from a GitHub repo and it is seeming more complicated than it should, but I can't seem to find a solution.

The problem: I have installed this project from GitHub into my web app (ASP.NET Core 2.0 React app using Typescript). I am now trying to import it, but am finding roadblocks at every turn.

It is similar to others, but the difference is that the others discuss their own components, while this is one from a repo belonging to someone else.

I can understand updating JS/JSX files with exports and such to accommodate issues such as this, but how can this be done when the module is being added from another project where updates may be regular?

Steps: 1. Install. npm install react-super-select --save 2. Add to webpack.config.js:

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const bundleOutputDir = './wwwroot/dist';
const superSelect = require('react-super-select');

module.exports = (env) => {
    const isDevBuild = !(env && env.prod);
    return [{
        stats: { modules: false },
        entry: { 'main': './ClientApp/boot.tsx' },
        resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
        output: {
            path: path.join(__dirname, bundleOutputDir),
            filename: '[name].js',
            publicPath: 'dist/'
        },
        module: {
            rules: [
                { test: /\.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' },
                { test: /\.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader?minimize' }) },
                { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
            ]
        },
        plugins: [
            new CheckerPlugin(),
            new superSelect(),
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./wwwroot/dist/vendor-manifest.json')
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new webpack.SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
            })
        ] : [
            // Plugins that apply in production builds only
            new webpack.optimize.UglifyJsPlugin(),
            new ExtractTextPlugin('site.css')
        ])
    }];
};
  1. Import into my .tsx file:

    import * as React from 'react'; import { RouteComponentProps, Redirect } from 'react-router'; import { ChangeEvent, Props, Key } from 'react'; import { formatDateInt, formatDatePeriod } from '../Dates'; import 'isomorphic-fetch'; import * as ReactSuperSelect from 'react-super-select';

This is where the errors start. With this setup, I get the following error:

TS7016  (TS) Could not find a declaration file for module 'react-super-select'. 'C:/AzTech/AzTechWebPortal/trunk/AzTechWebPortal/AzTechWebPortal/node_modules/react-super-select/lib/react-super-select.js' implicitly has an 'any' type.
  Try `npm install @types/react-super-select` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-super-select';

There is no @types/react-super-select and while looking into the declaration file error I found that the import can be changed to:

const ReactSuperSelect: any = require('react-super-select');

This raises no errors and I am able to add to the below component:

class Upload_FieldMapping extends React.Component<any, any> {
    constructor(props: any) {
        super(props);
        this.state = { items: [], loading: true };
        //PUT AN IF HERE TO HANDLE THIS BEING A SCHEDULE IMPORT
        fetch('api/Upload/FieldMappings')
            .then(response => response.json() as Promise<string[]>)
            .then(data => {
                this.setState({ items: data, loading: false });
            }).then(data => console.log(data));

    }

    public render() {
        type CostMap_Import = typeof CostMap_Import;
        type SchedMap_Import = typeof SchedMap_Import;
        let contents = this.state.loading        
            ? <p><em>Loading...</em></p>
            : Upload_FieldMapping.renderMappingsTable(this.state.items, this.props.selected === rdEV || 'undefined' ? CostMap_Import : SchedMap_Import);

        return <div>{contents}</div>
    }

    private static renderMappingsTable(values: string[], fMaps: any) {
        return <table className='table'>
            <tr>
                <ReactSuperSelect />
                </tr>
            <tr>
                {Object.keys(fMaps).map(function (i: Key) {
                    return <li key={i}>{i}</li>
                })}
            </tr>

        </table>
    }
}
  1. Run. Here's is what I am unable to get past. When running the app, the Configure method in Startup.cs complains:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    // global policy - assign here or on each controller
    app.UseCors("CorsPolicy");
    
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
        {
            HotModuleReplacement = true,
            ReactHotModuleReplacement = true
        });
    }
    

The error:

System.AggregateException
  HResult=0x80131500
  Message=One or more errors occurred.
  Source=mscorlib
  StackTrace:
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Microsoft.AspNetCore.Builder.WebpackDevMiddleware.UseWebpackDevMiddleware(IApplicationBuilder appBuilder, WebpackDevMiddlewareOptions options)
   at AzTechWebPortal.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in C:\AzTech\AzTechWebPortal\trunk\AzTechWebPortal\AzTechWebPortal\Startup.cs:line 47

Inner Exception 1:
NodeInvocationException: Cannot find module 'classnames'
Error: Cannot find module 'classnames'
    at Function.Module._resolveFilename (module.js:538:15)
    at Function.Module._load (module.js:468:25)
    at Module.require (module.js:587:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (C:\AzTech\AzTechWebPortal\trunk\AzTechWebPortal\AzTechWebPortal\node_modules\react-super-select\lib\react-super-select.js:1:2323)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)

If I need to create the declaration file, so be it. But will this always be the case for projects without a @types install?

For my sake and for others, what is the simplest way to get this done (that doesn't forego proper conventions)?

UPDATE Per the comment, I installed classnames & lodash:

npm install classnames --save
npm install lodash --save

And the error has changed to the following:

System.AggregateException
  HResult=0x80131500
  Message=One or more errors occurred.
  Source=mscorlib
  StackTrace:
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Microsoft.AspNetCore.Builder.WebpackDevMiddleware.UseWebpackDevMiddleware(IApplicationBuilder appBuilder, WebpackDevMiddlewareOptions options)
   at AzTechWebPortal.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in C:\AzTech\AzTechWebPortal\trunk\AzTechWebPortal\AzTechWebPortal\Startup.cs:line 47

Inner Exception 1:
NodeInvocationException: Cannot read property 'controlId' of undefined
TypeError: Cannot read property 'controlId' of undefined
    at new ReactSuperSelect (C:\AzTech\AzTechWebPortal\trunk\AzTechWebPortal\AzTechWebPortal\node_modules\react-super-select\lib\react-super-select.js:1:4130)
    at module.exports (C:\AzTech\AzTechWebPortal\trunk\AzTechWebPortal\AzTechWebPortal\webpack.config.js:28:13)
    at createWebpackDevServer (C:\AzTech\AzTechWebPortal\trunk\AzTechWebPortal\AzTechWebPortal\node_modules\aspnet-webpack\WebpackDevMiddleware.js:194:31)
    at createWebpackDevServer (C:\Users\EL-C\AppData\Local\Temp\emxsocle.wn2:74:50)
    at C:\Users\EL-C\AppData\Local\Temp\0dd3jvzv.ill:114:19
    at IncomingMessage.<anonymous> (C:\Users\EL-C\AppData\Local\Temp\0dd3jvzv.ill:133:38)
    at emitNone (events.js:106:13)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1055:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
reactjs
typescript
asp.net-core
asked on Stack Overflow Apr 10, 2018 by user • edited Apr 10, 2018 by user

1 Answer

0

The error is saying that you're missing the classnames npm modue. react-super-select has it, along with lodash, in its peerDepedencies so it's not installed automatically. Try installing them manually.

Also I don't think you need to add superSelect to webpack.config.js.

answered on Stack Overflow Apr 10, 2018 by eug

User contributions licensed under CC BY-SA 3.0