【问题标题】:React Module parse failed: Unexpected character '@'React 模块解析失败:意外字符“@”
【发布时间】:2019-05-20 17:31:00
【问题描述】:

尝试在我的反应组件中导入以下内容时出现错误:

import FontIconPicker from '@fonticonpicker/react-fonticonpicker';
import '@fonticonpicker/react-fonticonpicker/dist/fonticonpicker.base-theme.react.css';

我正在使用这个模块:https://fonticonpicker.github.io/react-fonticonpicker/

我收到此错误:

./node_modules/@fonticonpicker/react-fonticonpicker/dist/fonticonpicker.base-theme.react.css 模块解析失败:意外字符“@”(18:0)您可能需要一个 适当的加载器来处理这种文件类型。 | * | / | @font-face{font-family:fontIconPicker;src:url(assets/fontIconPicker.ttf) 格式(“truetype”),url(资产/fontIconPicker.woff) 格式(“woff”),url(资产/fontIconPicker.svg#fontIconPicker) format("svg");font-weight:400;font-style:normal}[class=" fipicon-"],[class^=fipicon-]{font-family:fontIconPicker!important;speak:none;font-style .......

这个错误可以用我在 github 上的代码重现:https://github.com/gregbia/my-app

使用npm installnpm start会显示错误。

我的 webpack 是这样的:

/**
 * Webpack Configuration
 *
 * Working of a Webpack can be very simple or complex. This is an intenally simple
 * build configuration.
 *
 * Webpack basics — If you are new the Webpack here's all you need to know:
 *     1. Webpack is a module bundler. It bundles different JS modules together.
 *     2. It needs and entry point and an ouput to process file(s) and bundle them.
 *     3. By default it only understands common JavaScript but you can make it
 *        understand other formats by way of adding a Webpack loader.
 *     4. In the file below you will find an entry point, an ouput, and a babel-loader
 *        that tests all .js files excluding the ones in node_modules to process the
 *        ESNext and make it compatible with older browsers i.e. it converts the
 *        ESNext (new standards of JavaScript) into old JavaScript through a loader
 *        by Babel.
 *
 * TODO: Instructions.
 *
 * @since 1.0.0
 */

const paths = require( './paths' );
const autoprefixer = require( 'autoprefixer' );
const ExtractTextPlugin = require( 'extract-text-webpack-plugin' );

// Extract style.css for both editor and frontend styles.
const blocksCSSPlugin = new ExtractTextPlugin( {
    filename: './dist/blocks.style.build.css',
} );

// Extract editor.css for editor styles.
const editBlocksCSSPlugin = new ExtractTextPlugin( {
    filename: './dist/blocks.editor.build.css',
} );

// Configuration for the ExtractTextPlugin — DRY rule.
const extractConfig = {
    use: [
        // "postcss" loader applies autoprefixer to our CSS.
        { loader: 'raw-loader' },
        {
            loader: 'postcss-loader',
            options: {
                ident: 'postcss',
                plugins: [
                    autoprefixer( {
                        browsers: [
                            '>1%',
                            'last 4 versions',
                            'Firefox ESR',
                            'not ie < 9', // React doesn't support IE8 anyway
                        ],
                        flexbox: 'no-2009',
                    } ),
                ],
            },
        },
        // "sass" loader converts SCSS to CSS.
        {
            loader: 'sass-loader',
            options: {
                // Add common CSS file for variables and mixins.
                data: '@import "./src/common.scss";\n',
                outputStyle: 'nested',
            },
        },
    ],
};

// Export configuration.
module.exports = {
    entry: {
        './dist/blocks.build': paths.pluginBlocksJs, // 'name' : 'path/file.ext'.
    },
    output: {
        // Add /* filename */ comments to generated require()s in the output.
        pathinfo: true,
        // The dist folder.
        path: paths.pluginDist,
        filename: '[name].js', // [name] = './dist/blocks.build' as defined above.
    },
    // You may want 'eval' instead if you prefer to see the compiled output in DevTools.
    devtool: 'cheap-eval-source-map',
    module: {
        rules: [
            {
                test: /\.(js|jsx|mjs)$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        // @remove-on-eject-begin
                        babelrc: false,
                        presets: [ require.resolve( 'babel-preset-cgb' ) ],
                        // @remove-on-eject-end
                        // This is a feature of `babel-loader` for webpack (not Babel itself).
                        // It enables caching results in ./node_modules/.cache/babel-loader/
                        // directory for faster rebuilds.
                        cacheDirectory: true,
                    },
                },
            },
            {
                test: /style\.s?css$/,
                exclude: /(node_modules|bower_components)/,
                use: blocksCSSPlugin.extract( extractConfig ),
            },
            {
                test: /editor\.s?css$/,
                exclude: /(node_modules|bower_components)/,
                use: editBlocksCSSPlugin.extract( extractConfig ),
            },
        ],
    },
    // Add plugins.
    plugins: [ blocksCSSPlugin, editBlocksCSSPlugin ],
    stats: 'minimal',
    // stats: 'errors-only',
    // Add externals.
    externals: {
        react: 'React',
        'react-dom': 'ReactDOM',
        ga: 'ga', // Old Google Analytics.
        gtag: 'gtag', // New Google Analytics.
        jquery: 'jQuery', // import $ from 'jquery' // Use the WordPress version.
    },
};

【问题讨论】:

    标签: reactjs webpack babeljs create-guten-block


    【解决方案1】:

    实际上,我很惊讶您在PostCSS 旁边使用了SCSS webpack 配置,因为使用little configuration 您可以预处理您的CSSes,然后将它们后处理为压缩版本SCSS 语法。我在this link 中为您设置了一个配置。我知道这不是你的主要问题,但我认为你的项目配置没有优化。

    上面的 webpack config 链接将帮助您更好地进行配置,您可以看到字体的 webpack 配置。无论如何...

    对于您的确切错误,您应该修复 webpack 上的字体配置,如下所示:

    {
      test: /\.(woff|woff2|eot|ttf|svg)$/,
      exclude: /node_modules/,
      loader: 'file-loader',
      options: {
        limit: 1024,
        name: '[name].[ext]',
        publicPath: 'dist/assets/',
        outputPath: 'dist/assets/'
      }
    },
    

    更新the repo:

    我编写webpack.config.dev.js 文件如下:

    const paths = require('./paths');
    const externals = require('./externals');
    const autoprefixer = require('autoprefixer');
    const ExtractTextPlugin = require('extract-text-webpack-plugin');
    
    // Extract style.css for both editor and frontend styles.
    const blocksCSSPlugin = new ExtractTextPlugin({
        filename: './dist/blocks.style.build.css',
    });
    
    // Extract editor.css for editor styles.
    const editBlocksCSSPlugin = new ExtractTextPlugin({
        filename: './dist/blocks.editor.build.css',
    });
    
    // Configuration for the ExtractTextPlugin — DRY rule.
    const extractConfig = {
        fallback: 'style-loader',
        use: [
            // "postcss" loader applies autoprefixer to our CSS.
            {loader: 'css-loader'},
            {
                loader: 'postcss-loader',
                options: {
                    ident: 'postcss',
                    plugins: [
                        autoprefixer({
                            browsers: [
                                '>1%',
                                'last 4 versions',
                                'Firefox ESR',
                                'not ie < 9', // React doesn't support IE8 anyway
                            ],
                            flexbox: 'no-2009',
                        }),
                    ],
                },
            },
            // "sass" loader converts SCSS to CSS.
            {
                loader: 'sass-loader',
                options: {
                    // Add common CSS file for variables and mixins.
                    data: '@import "./src/common.scss";\n',
                    outputStyle: 'nested',
                },
            },
        ],
    };
    
    // Export configuration.
    module.exports = {
        entry: {
            './dist/blocks.build': paths.pluginBlocksJs, // 'name' : 'path/file.ext'.
        },
        output: {
            // Add /* filename */ comments to generated require()s in the output.
            pathinfo: true,
            // The dist folder.
            path: paths.pluginDist,
            filename: '[name].js', // [name] = './dist/blocks.build' as defined above.
        },
        // You may want 'eval' instead if you prefer to see the compiled output in DevTools.
        devtool: 'cheap-eval-source-map',
        module: {
            rules: [
                {
                    test: /\.(js|jsx|mjs)$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            // @remove-on-eject-begin
                            babelrc: false,
                            presets: [require.resolve('babel-preset-cgb')],
                            // @remove-on-eject-end
                            // This is a feature of `babel-loader` for webpack (not Babel itself).
                            // It enables caching results in ./node_modules/.cache/babel-loader/
                            // directory for faster rebuilds.
                            cacheDirectory: true,
                        },
                    },
                },
                {
                    test: /style\.s?css$/,
                    exclude: /(node_modules|bower_components)/,
                    use: blocksCSSPlugin.extract(extractConfig),
                },
                {
                    test: /editor\.s?css$/,
                    exclude: /(node_modules|bower_components)/,
                    use: editBlocksCSSPlugin.extract(extractConfig),
                },
                {
                    test: /\.css$/,
                    include: /(node_modules\/@fonticonpicker\/react-fonticonpicker\/dist)/,
                    loaders: ['style-loader', 'css-loader']
                },
                {
                    test: /\.(woff|woff2|eot|ttf|svg)$/,
                    include: /(node_modules\/@fonticonpicker\/react-fonticonpicker\/dist)/,
                    loader: 'file-loader',
                    options: {
                        limit: 1024,
                        name: '[name].[ext]',
                        publicPath: 'dist/assets/',
                        outputPath: 'dist/assets/'
                    }
                }
            ],
        },
        // Add plugins.
        plugins: [blocksCSSPlugin, editBlocksCSSPlugin],
        stats: 'minimal',
        // stats: 'errors-only',
        // Add externals.
        externals: externals,
    };
    

    同时安装css-loaderfile-loader

    npm install file-loader css-loader
    

    提示:似乎字体需要在 webpack 配置中有一个 outputPath

    【讨论】:

      【解决方案2】:

      问题是 webpack 没有在 node_modules 中加载你的字体 @font-face。您正在排除从node_modules 加载css。但是你的@fonticonpicker/react-fonticonpicker/dist/fonticonpicker.base-theme.react.cssnode_modules

      在你的 webpack 配置中更改这个 sn-p

      {
        test: /style\.s?css$/,
        exclude: /(node_modules|bower_components)/,
        use: blocksCSSPlugin.extract( extractConfig ),
      },
      {
        test: /editor\.s?css$/,
        exclude: /(node_modules|bower_components)/,
        use: editBlocksCSSPlugin.extract( extractConfig ),
      },
      

      {
        test: /style\.s?css$/,
        use: blocksCSSPlugin.extract( extractConfig ),
      },
      {
        test: /editor\.s?css$/,
        use: editBlocksCSSPlugin.extract( extractConfig ),
      },
      { test: /(\.css$)/, // you need to load all css imported from node_modules
        loaders: ['style-loader', 'css-loader', 'postcss-loader']
      }
      

      【讨论】:

        【解决方案3】:

        您似乎缺少 css-loader 来存储在 node_modules 中的 .css。这就是为什么你要面对这个issue。运行 npm i -D css-loader 并将此规则添加到您的 node_modules &gt; cgb-scrips &gt; config &gt; webpack.config.&lt;env&gt;.js 文件中:

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

        或者,要跳过编辑webpack.config.js,您可以像这样简单地导入文件:

        import 'raw-loader!css-loader!@fonticonpicker/react-fonticonpicker/dist/fonticonpicker.base-theme.react.css';
        import 'raw-loader!css-loader!@fonticonpicker/react-fonticonpicker/dist/fonticonpicker.material-theme.react.css';
        

        【讨论】:

          【解决方案4】:

          您在 webpack 中的 loader 配置与 CSS 文件 Route 不匹配。

          import '@fonticonpicker/react-fonticonpicker/dist/fonticonpicker.base-theme.react.css';
          

          既不是style.css 也不是editor.css。因此你得到一个错误。此外,您在 webpack 加载器配置中忽略了 node_modules,但您从 node_modules 导入了 css。

          添加

            {
                 test: /react\.s?css$/,
                 use: [{
                  loader: 'css-loader',
                  options: {
                    modules: true
                  }
                }],
            },
          

          应该工作

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-12-31
            • 2017-04-04
            • 2019-07-18
            • 2017-09-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多