Минимальная настройка Webpack 2 для BlueprintJS не загружает CSS

Я пытаюсь создать простую настройку webpack 2 для экспериментов с BlueprintJS и TypeScript. Кажется, я близок к этому, но CSS не загружается должным образом.

Вот структура каталогов для этого проекта

  • src/
    • index.tsx
    • App.tsx
    • App.css
  • index.html
  • пакет.json
  • tsconfig.json
  • webpack.config.js

App.tsx в настоящее время содержит один компонент Button, который должен отображать значок обновления. Когда я запускаю npm run build, веб-пакет указывает, что стили были загружены. Однако когда я запускаю npm run start и просматриваю приложение, у кнопки нет значка и других стилей CSS.

Должно быть, я делаю что-то не так. Кто-нибудь может это заметить? Исходники всех файлов приведены ниже. Бонусные баллы, если вы сможете понять, почему сервер webpack-dev-server не будет перекомпилирован при изменении текста Button в App.tsx. Другие предложения приветствуются.

index.tsx

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

App.tsx

import * as React from "react";
import { Button } from "@blueprintjs/core";
import './App.css';

export class App extends React.Component<{}, {}> {
     public render(): JSX.Element {
        return (
                <Button iconName="refresh" text="Refresh"/>
        );
    }
}
export default App;

App.css

@import "@blueprintjs/core/dist/blueprint.css";

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>BlueprintJS Test</title>
</head>
<body>
    <div id="root"></div>
    <script src="./node_modules/react/dist/react.js"></script>
    <script src="./node_modules/react-dom/dist/react-dom.js"></script>
    <script type="text/javascript" src="./dist/bundle.js"></script>
</body>
</html>

пакет.json

{
  "name": "blueprintplay",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server"
  },
  "dependencies": {
    "@blueprintjs/core": "^1.14.0",
    "classnames": "^2.2.5",
    "react": "^15.4.2",
    "react-addons-css-transition-group": "^15.4.2",
    "react-dom": "^15.4.2"
  },
  "devDependencies": {
    "@types/classnames": "^0.0.32",
    "@types/pure-render-decorator": "^0.2.27",
    "@types/react": "^15.0.18",
    "@types/react-addons-css-transition-group": "^15.0.1",
    "@types/react-dom": "^0.14.23",
    "case-sensitive-paths-webpack-plugin": "^2.0.0",
    "css-loader": "^0.28.0",
    "file-loader": "^0.11.1",
    "source-map-loader": "^0.2.0",
    "style-loader": "^0.16.1",
    "ts-loader": "^2.0.3",
    "typescript": "^2.2.2",
    "url-loader": "^0.5.8",
    "webpack": "^2.4.1",
    "webpack-dev-server": "^2.4.2"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "module": "commonjs",
    "target": "es5",
    "jsx": "react"
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"      
  ]
}

webpack.config.js

const path = require('path');

module.exports = {
  entry: [
    './src/index.tsx'
  ],
  output: {
    filename: 'bundle.js',
    path: __dirname + "/dist"
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        loader: "source-map-loader"
      },
      {
        test: /\.tsx?$/,
        use: "ts-loader"
      },
     {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              modules: true,
            },
          },
        ],
      },
      {
        test: /\.(woff|woff2)$/,
        use: {
          loader: 'url-loader',
          options: {
            name: 'fonts/[hash].[ext]',
            limit: 5000,
            mimetype: 'application/font-woff'
          }
        }
      }, 
      {
        test: /\.(ttf|eot|svg)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: 'fonts/[hash].[ext]'
          }
        }
      },
    ]
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"]
  },
  devtool: 'source-map',
  devServer: {
    host: process.env.HOST, // Defaults to `localhost`
    port: process.env.PORT, // Defaults to 8080
    hot: true,
  }, 
  externals: {
    "react": "React",
    "react-dom": "ReactDOM"
  },
  stats: "verbose",
};

person Richard C. Davis    schedule 21.04.2017    source источник


Ответы (1)


Вы используете модули CSS, которые изменяют каждый класс на локальный идентификатор, и вам потребуется для ссылки на правильный идентификатор. Но поскольку это библиотека, которая устанавливает классы для элемента, например, для кнопки, которую вы используете, она не будет работать с модулями CSS, поэтому вам нужно отключить их в файле css-loader. Вы можете просто удалить эту опцию, потому что по умолчанию они отключены.

{
  test: /\.css$/,
  use: [
    {
      loader: 'style-loader',
    },
    {
      loader: 'css-loader',
    },
  ],
},

С отключенными модулями CSS вам также необходимо изменить импорт в вашем CSS, потому что он рассматривается как относительный путь. Webpack позволяет вам начинать путь с ~, чтобы указать, что он должен быть разрешен как модуль, а не как относительный путь.

@import "~@blueprintjs/core/dist/blueprint.css";
person Michael Jungo    schedule 21.04.2017