【问题标题】:Configure webpack to output images/fonts in a separate subfolders配置 webpack 以在单独的子文件夹中输出图像/字体
【发布时间】:2016-01-08 14:58:44
【问题描述】:

我管理配置 webpack 以将 CSS 和 JS 输出到各自的子目录中,即 public/asests/csspublic/assets/js。但是,我不知道如何对图像和字体做同样的事情。

换句话说,我想将public/assets/images 文件夹中的图像和字体输出到public/assets/fonts 文件夹中。

这是我的 webpack 配置文件:

var path = require('path');
var ExtractCSS = require('extract-text-webpack-plugin');

module.exports = {
    context: path.resolve('private/js'),
    resolve: ['', '.js', '.jsx', '.es6', '.json'],
    entry: {
        homepage: './homepage'
    },
    output: {
        path: path.resolve('public/assets'),
        publicPath: '/public/assets/',
        filename: 'js/[name].js'
    },
    plugins: [
        new ExtractCSS('css/[name].css')
    ],
    devServer: {
        contentBase: 'public'
    },
    module: {
        loaders: [
            {
                test: /\.(es6|js|jsx)$/,
                exclude: /node_modules/,
                loader: 'babel-loader'
            },
            {
                test: /\.css$/,
                exclude: /node_modules/,
                loader: ExtractCSS.extract('style-loader', 'css-loader')
            },
            {
                test: /\.less$/,
                exclude: /node_modules/,
                loader: ExtractCSS.extract('style-loader', 'css-loader!less-loader')
            },
            {
                test: /\.(jpg|jpeg|gif|png|woff|woff2|eot|ttf|svg)$/,
                exclude: /node_modules/,
                loader: 'url-loader?limit=1024'
            }
        ]
    }
}

【问题讨论】:

    标签: webpack


    【解决方案1】:

    Webpack 5案例-

    保留它以防万一有人正在寻找 Webpack 5 解决方案来满足将图像/字体资产输出到单独目录中的输出路径的要求。

    Webpack 5 用 Assets Module 替换了 raw-loaderurl-loaderfile-loader,它有 4 个新模块来处理资产。在此处阅读更多详细信息 - https://webpack.js.org/guides/asset-modules/

    对于我们的问题陈述,以下配置将所有字体/svgs 输出到目录fonts。但如果某些文件小于 8KB,它会将它们内联。

      {
        test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
        type: 'asset',   // <-- Assets module - asset
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024 // 8kb
          }
        },
        generator: {  //If emitting file, the file path is
          filename: 'fonts/[hash][ext][query]'
        }
      }
    

    同样,我们也可以对图像做同样的事情 -

      {
        test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
        type: 'asset/resource',  //<-- Assets module - asset/resource
        generator: {
          filename: 'images/[hash][ext][query]'
        }
      }
    

    无论文件大小如何,都将所有图像输出到images 目录。

    【讨论】:

      【解决方案2】:

      配置文件/url-loader 输出路径和文件名

      你可以读到official file-loader documentation:配置对象中有一个name参数,可以指定路径。

      这样就可以了:

                               // ...
              {
                  test    : /\.(woff|woff2|ttf|eot)$/,
                  loader  : 'url-loader',
                  options: {
                      limit : 70000,
                      name: 'fonts/[name].[ext]'
                  }
              },
                               // ...
      

      我建议你看看available placeholders,了解文件名中可以​​使用什么。

      加载器通常有一个可用的配置对象,即使您可以像其他开发人员建议的那样传递选项 ( loader:'url-loader?limit=1024&amp;name=images/[name].[ext]') 我更喜欢使用简单的对象配置,以获得更易读、更易于配置/调试的内容

      输出路径

      有一个outputPath(可选)配置参数,以防万一想要覆盖默认输出路径,无论如何都必须配置它(check the docs)。 我很确定它的加载器的 webpack 将使用默认的输出目录。在我的项目中,我有这个:

                               // ...
      output: {
          path: helpers.publicPath(),      // local output path: <project-root>/public
          publicPath,                      // same path on the server: /myapp/public
          filename: 'js/[name].bundle.js', // default output configuration for js
          chunkFilename: 'js/[name].chunk.js'
      },
                               // ...
      

      注意

      我不确定您是否需要排除 node_modules 文件夹:如果使用了诸如 font-awesome 或 material-icons 之类的库,那么您需要包含 node_modules。 Webpack 将自动删除对构建和运行项目无用的文件。 我只会排除包含不使用导入和类似东西的旧旧脚本的文件夹,并且无论如何我都不希望被 webpack 考虑。

      【讨论】:

        【解决方案3】:

        我可以通过file-loader 解决这个问题 如果您使用的是 Webpack 4,则应使用 use 而不是 loader

        {
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: ['file-loader?name=fonts/[name].[ext]']
        }
        

        【讨论】:

          【解决方案4】:
          { 
              test: /\.(ttf|eot|svg|woff2?)(\?v=[a-z0-9=\.]+)?$/i,
              include: folders.npm,
              loader: 'file?name=fonts/[name].[ext]'
          },
          {
              test: /\.(jpe?g|png|gif|svg|ico)$/i,
              include: folders.src,
              loaders: [
                  'file?name=images/[sha512:hash:base64:7].[ext]',
                  'image-webpack?progressive=true&optimizationLevel=7&interlaced=true'
              ]
          }
          

          这是我在生产中使用的。我经常遇到使用 *.svg 图片和 SVG 字体作为 IE 后备的情况。这里我假设字体总是在 node_modules 中。我还看到开发人员在做test: /fonts\/[w+].(svg|eot ....)

          【讨论】:

          • 我不知道这是否是标准节点实践,但使用 /node_modules/ 而不是 folder.npm 帮助了我。我喜欢你的方法,因为我的字体也来自 node_modules 文件夹
          • folders.npm 是我在开头声明的变量。 const paths = { root: path.resolve('.'), npm: path.resolve('.', '/node_modules') ... etc. };
          • 您能查看我的帖子吗?在我的最后一条评论 github.com/webpack-contrib/file-loader/issues/299 中有一个 git repo
          • 嘿@RickSanchez。我猜它与 sass/postcss 加载器有关。我记得在解决这两个问题时遇到了问题。在某些情况下,我想包含 font-awesome,但在 scss 中包含 css 会有奇怪的行为。 CSS 内部的路径是完整的,据我所知,FA 的 css 使用相对路径。建议。尝试最小化配置。当使用生产模式的 webpack 时,删除“最小化”字段,因为它们是 true。现在也忽略 sourceMap 。移除 outputPath 和 publicPath 以获得公共资产的扁平结构,然后我们可以在此基础上进行构建。
          【解决方案5】:

          我可以通过参考 GitHub 上的 url-loaderfile-loader 文档来解决这个问题。

          所有,我需要做的是在加载器中添加一个 name 查询字符串参数来指定完整路径。我还了解到,您可以在输出位置指定文件的命名方式。

          {
              test: /\.(jpg|jpeg|gif|png)$/,
              exclude: /node_modules/,
              loader:'url-loader?limit=1024&name=images/[name].[ext]'
          },
          {
              test: /\.(woff|woff2|eot|ttf|svg)$/,
              exclude: /node_modules/,
              loader: 'url-loader?limit=1024&name=fonts/[name].[ext]'
          }
          

          【讨论】:

          • 嘿,这真的很有帮助。但由于某种原因,只有字体对我有用。图像不会导出到新的图像文件夹中。我是否缺少插件或者我使用 SVG 的事实是否会成为问题?
          • 我遇到了同样的问题。我通过使用文件加载器而不是图像的 url-loader 来修复它loader:'file?limit=1024&amp;name=images/[name].[ext]'
          • 这是针对 webpack 1 的吗?我收到此错误:Can't resolve 'file-loader&amp;name=images/[name].[ext]
          • 很棒的答案,非常有用,但请注意 ?limit=1024&amp;name= 中的 name 查询是 dist CSS 文件中字体的正确路径。
          • 我已经使用 Webpack 好几年了,从来没有想过这个问题。非常有帮助,谢谢!
          猜你喜欢
          • 2016-03-05
          • 2017-07-11
          • 2017-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-01
          • 1970-01-01
          相关资源
          最近更新 更多