Webpack 2 语义问题 UI

Webpack 2 issues with Semantic UI

一直在努力使用 Webpack 2 设置语义-ui。我有一些与默认语义-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 文件中,如 this example.[=37= 中所示]

我一直在关注 this guide to get semantic-ui setup with Webpack 1 using Webpack 2, fixing the less-loader differences along the way. Nevertheless, I can't seem to fix these issues after scouring other projects like 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 文件夹,然后 build semantic 有点像 this tutorial
  2. postinstall 脚本用我的版本替换所有 theme.config 导入(RewriteImportPlugin 应该处理的)
  3. 设置一个单独的gulp任务来处理文件的移动和ui语义的建立-ui
  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

希望这会为您指明正确的方向,尽管它不是一个完整的解决方案。正如我提到的,我花了很多时间试图让 Semantic-UI 使用 Webpack 2。我正在使用 vue-cli 的 Webpack template 用于 VueJS 项目。我尝试从模板中剥离 Vue 配置以获取与框架无关但效果不佳的示例。

看起来您可能只是在尝试获取 Semantic-UI CSS 设置,而不是他们的 JS 组件。我对Vue Webpack模板所做的所有添加都与JS有关,基本上只是为了包含jQuery for 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'

折腾了三天,终于想通了大半。

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加载程序之后(错误在哪里仍然是个谜)。我创建了一个 handy template 作为非常 最小 的示例,其中包含一些额外的细节。

这应该是为 webpack2 制作语义 ui 主题的最优雅的方式。

感谢这个issue, I have updated my tutorial React+Webpack1/2/3+Semantic UI and how to do theming and the demo project

的想法

请按照教程或滚动到底部查看您需要进行的主要更改。与 Webpack1 的这两个主要区别是:

  • 默认情况下,less-loader会使用webpack的解析器来解析所有less文件,导致less-plugin-rewrite-import等插件无法处理less文件。这就是为什么你会发现该插件不适用于 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;