Typescript + Webpack + node_modules разрешение

У меня есть проект, над которым я работаю - написанный на Typescript (2.4), связанный с Webpack (3.5), и некоторые зависимости узлов. Он имеет клиентскую и серверную части, каждая в своей собственной подпапке. Вскоре я понял, что они разделяют много кода, и добавил еще одну "общую" папку верхнего уровня - и в обоих tsconfig.json файлы, которые я добавил:

...
"include": [
    "*.ts",
    "../shared/*.ts",
]
...

Все это работало замечательно, но вскоре эти общие файлы стали иметь собственные зависимости. Я подумал, что поскольку общие файлы на самом деле не создаются сами по себе - владение зависимостями будет принадлежать каталогам Server и Client. Что-то вроде этого:

project
| server
|  | node_modules
|  |  |  @types
|  |  |  |  some-npm-library
|  |  |  some-npm-library
|  | main.ts
|  | SomeServerClass.ts   (inherits ../shared/BaseClass)
|  | tsconfig.json
|  | webpack.config.js
| client
|  | node_modules
|  |  |  @types
|  |  |  |  some-npm-library
|  |  |  some-npm-library
|  | main.ts
|  | SomeClientClass.ts   (inherits ../shared/BaseClass)
|  | tsconfig.json
|  | webpack.config.js
| shared
|  | BaseClass.ts    (Has an dependency on some npm thing)
|  | otherstuff.ts

Когда я бегу tsc - компилируется без ошибок. Но webpack, кажется, никогда не находит зависимости node_modules, с Error: Can't resolve 'some-npm-library',

Клиент tsconfig.json:

{
    "compilerOptions": {
        "target": "es2017",
        "module": "commonjs",
        "baseUrl": "./",
        "sourceMap": true,
        "outDir": "./build",
        "typeRoots": ["./node_modules/@types"],
        "types": ["some-npm-library"],
        "lib": [ "es6", "dom", "es2017.object", "es2016.array.include" ]
    },
    "include": [
        "*.ts",
        "..shared/**.ts"
    ]
}

Клиент webpack.config.js

const path = require('path');

module.exports = {
    entry: "./main.ts",
    target: "web",
    output: {
        filename: "app.js",
        path: __dirname + "/bin"
    },
    watch: true,

    devtool: "source-map",

    resolve: {
        extensions: [".ts", ".js", ".json"],                  
    },

    module: {
        rules: [
            { test: /\.ts$/, loader: "ts-loader" },    
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    }
};

1 ответ

Using this webpack.config.ts file with proper file path:

var fs = require('fs');
var path = require('path');

var nodeModules = {};
fs.readdirSync('node_modules')
  .filter(function (x) {
    return ['.bin'].indexOf(x) === -1;
  })
  .forEach(function (mod) {
    nodeModules[mod] = 'commonjs ' + mod;
  });

module.exports = {
  entry: './app/server.ts',
  mode: 'development',
  output: {
    path: __dirname + '/dist',
    publicPath: '/',
    filename: 'server.js',
  },
  resolve: {
    // Add '.ts' and '.tsx' as a resolvable extension.
    extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js'],
  },

  module: {
    // loaders: [
    rules: [
      // All files with a '.ts' or '.tsx'
      // extension will be handled by 'ts-loader'
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
      },
    ],
  },
  target: 'node',
  externals: nodeModules,
};

Что сработало для меня:

Я нашел решение - оно может не работать для других людей в подобных ситуациях - но я использовал Resolve.alias Webpack. Добавив в строку, например, так:

alias: {
   'npm-library': path.resolve(__dirname, 'node_modules/npm-library/')
}

Который заставит webpack смотреть на import * from 'npm-library' и узнайте это - несмотря на то, что в этой общей папке нет библиотеки npm.

Также, возможно, попробуйте:

Я также попытался установить зависимости в общую папку - а не на клиент и сервер по отдельности - проблема заключалась в том, что у меня были дублирующиеся зависимости. Но быть осторожным, чтобы избежать этого, может также сработать.

Другие вопросы по тегам