Проблемы Webpack 2 с семантическим интерфейсом пользователя

Я изо всех сил пытался получить настройку semantic-ui с помощью Webpack 2. У меня несколько ошибок, связанных со шрифтами в теме semantic-ui по умолчанию, и еще одна ошибка, касающаяся image-webpack-loader:

ERROR in ./~/css-loader?{"lessPlugins":[{"options":{"paths":{"../../theme.config":"/Users/djthomps/Desktop/demo/theme.config"}}}]}!./~/less-loader!./semantic/src/semantic.less
Module not found: Error: Can't resolve './themes/themes/default/assets/fonts/icons.eot' in '/Users/djthomps/Desktop/demo/semantic/src'
 @ ./~/css-loader?{"lessPlugins":[{"options":{"paths":{"../../theme.config":"/Users/djthomps/Desktop/demo/theme.config"}}}]}!./~/less-loader!./semantic/src/semantic.less 6:285117-285174 6:285197-285254
 @ ./semantic/src/semantic.less
 @ ./app/index.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 ./app/index.js

# same for icons.woff2

# same for icons.woff

# same for icons.ttf

# same for icons.svg

ERROR in ./~/css-loader?{"lessPlugins":[{"options":{"paths":{"../../theme.config":"/Users/djthomps/Desktop/demo/theme.config"}}}]}!./~/less-loader!./semantic/src/semantic.less
Module not found: Error: Can't resolve 'image-webpack' in '/Users/djthomps/Desktop/demo'
BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.
                 You need to specify 'image-webpack-loader' instead of 'image-webpack'.
 @ ./~/css-loader?{"lessPlugins":[{"options":{"paths":{"../../theme.config":"/Users/djthomps/Desktop/demo/theme.config"}}}]}!./~/less-loader!./semantic/src/semantic.less 6:218646-218697
 @ ./semantic/src/semantic.less
 @ ./app/index.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 ./app/index.js

Конечная цель - использовать компоненты React semantic-ui с настраиваемой темой, которую я могу просто импортировать в свои .jsx файлы, как показано в этот пример.

Я следил за этим руководством по настройке семантического пользовательского интерфейса с помощью Webpack 1 с помощью Webpack 2, исправляя различия в less-loader . Тем не менее, я не могу исправить эти проблемы после изучения других проектов, таких как font-awesome- webpack2 и просмотр комментариев на github. Вот очень маленький, проверяемый пример:

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const RewriteImportPlugin = require('less-plugin-rewrite-import');

const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
    template: './app/index.html',
    filename: 'index.html',
    inject: 'body' // inject scripts before closing body tag
});

module.exports = {
    entry: './app/index.js', // where the bundler starts the bundling process
    output: { // where the bundled code is saved
        path: path.resolve('dist'),
        filename: 'index_bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.(png|jpg|gif|woff|svg|eot|ttf|woff2)$/,
                loader: 'url-loader?limit=1024&name=[name]-[hash:8].[ext]!image-webpack'
            },
            {
                test: /\.less$/, // import css from 'foo.less';
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            // importLoaders: 1,
                            lessPlugins: [
                                new RewriteImportPlugin({
                                    paths: {
                                        '../../theme.config':  __dirname + '/theme.config',
                                    },
                                })
                            ]
                        }
                    },
                    'less-loader'
                ]
            },
            {
                test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: 'file-loader'
            }
        ]
    },
    devtool: 'eval-source-map',
    devServer: { compress: true },
    plugins: [ HtmlWebpackPluginConfig ]
};

package.json

{
    "name": "demo",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "scripts": {
        "start": "webpack-dev-server"
    },
    "devDependencies": {
        "css-loader": "^0.26.1",
        "html-webpack-plugin": "^2.28.0",
        "image-webpack-loader": "^3.2.0",
        "less-loader": "^2.2.3",
        "less-plugin-rewrite-import": "^0.1.1",
        "semantic-ui": "^2.2.7",
        "style-loader": "^0.13.1",
        "url-loader": "^0.5.7",
        "webpack": "^2.2.1",
        "webpack-dev-server": "^2.3.0"
    }
}

app/index.js

import css from '../semantic/src/semantic.less';

app/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>
    <button class="ui button">Follow</button>
</body>
</html>

theme.config

 // truncated for brevity
 @button     : 'gmail';

Моя структура проекта следующая:

.
├── app
│   ├── index.html
│   └── index.js
├── package.json
├── semantic
│   ├── gulpfile.js
│   ├── src
│   └── tasks
├── semantic.json
├── theme.config
└── webpack.config.js

Обновление 1

Я обдумывал возможные решения:

  1. postinstall, который перемещает мой theme.config в папку semantic, а затем создает semantic что-то вроде этого руководства
  2. postinstall сценарий для замены всего theme.config импорта моей версией (что RewriteImportPlugin должно обрабатывать)
  3. Настройте отдельную задачу gulp для обработки перемещения файлов и создания семантического пользовательского интерфейса.
  4. Использовать сквозной webpack 2 (предпочтительно)

Обновление 2

ERROR in ./~/css-loader?{"lessPlugins":[{"options":{"paths":{"../../theme.config":"/Users/djthomps/Desktop/demo/theme.config"}}}]}!./~/less-loader!./semantic/src/semantic.less
Module not found: Error: Can't resolve 'image-webpack' in '/Users/djthomps/Desktop/demo'
BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.
                 You need to specify 'image-webpack-loader' instead of 'image-webpack'.
 @ ./~/css-loader?{"lessPlugins":[{"options":{"paths":{"../../theme.config":"/Users/djthomps/Desktop/demo/theme.config"}}}]}!./~/less-loader!./semantic/src/semantic.less 6:218646-218697
 @ ./semantic/src/semantic.less
 @ ./app/index.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 ./app/index.js

исправлено настройкой файла конфигурации:

 loader: 'url-loader?limit=1024&name=[name]-[hash:8].[ext]!image-webpack-loader' // note the loader at the end

person djthoms    schedule 18.02.2017    source источник
comment
Если вы хотите использовать семантику с React, они работают над хорошей библиотекой компонентов: react.semantic-ui. ru / Introduction. Вам все равно нужно включить CSS вручную. С любым настраиваемым css / sass ... Удачи, я потратил много времени, чтобы заставить его работать.   -  person Balázs Édes    schedule 19.02.2017
comment
@ BalázsÉdes Я знаю библиотеку компонентов. Идея в том, что я хочу иметь возможность внедрить свою собственную тему и импортировать .less файлы прямо в компонент.   -  person djthoms    schedule 19.02.2017
comment
Итак, я могу вам сказать, что я тоже потратил смехотворно много времени на это (для использования с VueJS), и, наконец, я просто построил семантический пользовательский интерфейс, используя их задачу gulp, и включил сгенерированные файлы CSS и JS из семантики dist. На самом деле он работает очень хорошо, gulp watch фиксирует изменения в теме и перестраивает, а затем выполняет горячую перезагрузку веб-пакетов,   -  person Justin    schedule 19.02.2017
comment
@Justin На самом деле я пошел по этому пути ... Приятно знать, что другие борются с тем же и думают о том же.   -  person djthoms    schedule 19.02.2017
comment
@Justin, не могли бы вы рассказать подробнее, как это работает с помощью Webpack 2? Я все еще получаю те же ошибки, когда использую обычный старый CSS   -  person djthoms    schedule 19.02.2017


Ответы (3)


После того, как я бился головой в течение трех дней, я наконец смог понять это по большей части.

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './app/index.js', // where the bundler starts the bundling process
    output: { // where the bundled code is saved
        path: path.resolve('dist'),
        filename: 'index_bundle.js'
    },
    resolve: {
        alias: {
            semantic: path.resolve(__dirname, 'semantic/src/'),
            jquery: path.resolve(__dirname, 'node_modules/jquery/src/jquery')
        }
    },
    module: {
        loaders: [
            {
                test: /\.(png|gif)$/,
                loader: 'url-loader?limit=1024&name=[name]-[hash:8].[ext]!image-webpack-loader'
            },
            {
                test: /\.jpg$/,
                loader: 'file-loader'
            },
            {
                test: /\.less$/, // import css from 'foo.less';
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            },
            {
                test: /\.(ttf|eot|svg|woff2?)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: 'file-loader'
            }
        ]
    },
    devtool: 'eval-source-map',
    devServer: { compress: true },
    plugins: [
        new HtmlWebpackPlugin({
            template: './app/index.html',
            filename: 'index.html',
            inject: 'body' // inject scripts before closing body tag
        }),
        new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery'
    })
    ]
};

но загвоздка в том, что если вы хотите использовать объединенные шрифты, вам необходимо исправить пути, потому что они разрешены неправильно после, мы запускаем загрузчик less-loader (где ошибка остается загадкой). Я создал удобный шаблон как очень минимальный пример с некоторыми дополнительными деталями.

person djthoms    schedule 20.02.2017

Надеюсь, это укажет вам правильное направление, даже если это не полное решение. Как я уже упоминал, я потратил невероятное количество времени, пытаясь заставить Semantic-UI работать с Webpack 2. Я использую Шаблон Webpack из vue-cli для проекта VueJS. Я попытался убрать конфигурацию Vue из шаблона, чтобы получить пример, не зависящий от фреймворка, но это не сработало.

Похоже, вы просто пытаетесь получить настройку Semantic-UI CSS, а не их JS-компоненты. Все дополнения, которые я внес в шаблон Vue Webpack, связаны с JS, в основном просто для включения jQuery для Semantic-UI. Так что, если вас интересует только работа CSS, в этих дополнениях нет необходимости.

Чтобы настроить конфигурацию шаблона для работы с Semantic-UI JS, я добавил это в module-exports

alias: {
  ...
  jquery: "jquery/src/jquery",
},
...
plugins: [
  new webpack.ProvidePlugin({
    $: "jquery",
    jQuery: "jquery",
    "window.jQuery": "jquery"
  })
]  

Я запускаю задачу Semantic Gulp для сборки в свою собственную папку dist, а затем могу просто включить эти файлы в свою запись main.js для webpack.

import '../semantic/dist/semantic.css'
import '../semantic/dist/semantic'
person Justin    schedule 19.02.2017

Это должен быть самый элегантный способ заставить работать семантическую тематику пользовательского интерфейса для webpack2.

Спасибо за идею из этой проблемы, у меня обновил мой учебник React + Webpack1 / 2/3 + Семантический интерфейс и создание тем и демонстрационный проект

Следуйте инструкциям или прокрутите вниз, чтобы увидеть основные изменения, которые вам необходимо внести. Эти два ключевых отличия от Webpack1:

  • По умолчанию less-loader будет использовать преобразователь webpack для разрешения всех файлов less, в результате чего такие плагины, как less-plugin-rewrite-import, не смогут обрабатывать меньше файлов. Вот почему вы обнаружите, что плагин не работает для webpack2. Чтобы заставить less-loader использовать собственный преобразователь, вам необходимо вручную указать пути к параметрам для поиска (взгляните на конфигурацию webpack, вставленную ниже)
  • Поскольку теперь мы используем меньше резолвера, мы больше не можем использовать ~ для ссылки на модули в node_modules, поэтому откройте свой theme.config и измените @import "~semantic-ui-less/theme.less"; на @import "semantic-ui-less/theme.less";

    const path = require('path');
    const webpack = require('webpack');
    const RewriteImportPlugin = require("less-plugin-rewrite-import");
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const ROOT_DIR = path.resolve(__dirname);
    const SRC_DIR = path.resolve(__dirname, 'app');
    const BUILD_DIR = path.resolve(__dirname, 'build');
    const NODE_MODULES_DIR = path.resolve(__dirname, 'node_modules');

    var webpackConfig = {
      devtool: 'eval',
      entry: {
        index: path.resolve(SRC_DIR, 'index.js'),
      },
      output: {
        path: BUILD_DIR,
        filename: '[name].[hash:8].js',
      },
      resolve: {
        modules: [ROOT_DIR, 'node_modules'],
      },
      module: {
        rules: [
          {
            test: /\.(less|config)/,
            use: [
              'style-loader',
              'css-loader',
              {
                loader: 'less-loader',
                options: {
                  paths: [ROOT_DIR, NODE_MODULES_DIR],
                  plugins: [
                    new RewriteImportPlugin({
                      paths: {
                        '../../theme.config':  __dirname + '/app/semantic-ui/theme.config',
                      },
                    }),
                  ],
                },
              },
            ],
          },
          {
            test: /\.(png|jpg|gif|woff|svg|eot|ttf|woff2)$/,
            use: [
              { loader: 'file-loader' },
            ],
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            test: /\.jsx?$/,
            exclude: /(node_modules|bower_components)/,
            loader: 'babel-loader',
            query: {presets: ['es2015']}
          },
        ],
      },

      plugins: [
        new HtmlWebpackPlugin({
          inject: 'body',
          template: 'app/index.html',
          filename: 'index.html',
          chunks: ['index'],
          chunksSortMode: 'dependency',
          env: process.env,
        }),
      ],
    };

module.exports = webpackConfig;
person Neekey    schedule 27.06.2017