首页 > 解决方案 > Webpack 不会解析 js 文件中的资产别名

问题描述

我创建了一个 webpack 配置,其中有“assets”、“styles”、“scripts”和“twig. 因为我的“构建”布局与“开发”环境不同,所以我创建了一些别名来解决。

问题

当运行 webpack (dev-mode & prod-mode) 时,它看起来几乎可以完美运行。除了一些别名:

我的结构

- src
  - favicon
      - favicon.ico
  - fonts
    - poppins-v9-latin-500.ttf
    - (some more)
  - images
    - test.png
  - partials
    - layout.twig
  - scripts
    - index.js
    - canvas.js
  - styles
    - sass
      - fonts.scss
    - style.scss
  - index.twig
- webpack
  - webpack.common.js
  - webpack.config.dev.js
  - webpack.config.prod.js
- node_modules
- package.json
- .htaccess
- .babelrc

我的 Webpack 配置

webpack.common.js

const Path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    app: Path.resolve(__dirname, '../src/scripts/index.js'),
  },
  output: {
    path: Path.join(__dirname, '../dist'),
    filename: 'js/[name].js',
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
      name: false,
    },
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: Path.resolve(__dirname, '../src/index.twig'),
    })
  ],
  module: {
    rules: [
      {
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      },
      {
        test: /\.twig$/,
        use: [
          'raw-loader',
          'twig-html-loader'
        ],
      },
    ],
  },
};

webpack.config.dev.js

const Path = require('path');
const Webpack = require('webpack');
const { merge } = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const common = require('./webpack.common.js');

// Let us use Node JS
const fs = require('fs');

// Get all pages in /src by filtering .twig
const pages = fs.readdirSync(Path.resolve(__dirname, '../src/')).
  filter(fileName => fileName.endsWith('.twig') && fileName !== 'index.twig');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'cheap-eval-source-map',
  output: {
    chunkFilename: 'js/[name].chunk.js',
  },
  devServer: {
    inline: true,
    hot: true
  },
  plugins: [
    new Webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('development'),
    }),
    ...pages.map(page => new HtmlWebpackPlugin({
      template: Path.resolve(__dirname, ('../src' + page)),
      filename: page.replace('.twig', ''),
    })),
  ],
  resolve: {
    alias: {
      FaviconFiles: Path.resolve(__dirname, '../src/favicon'),
      ScriptFiles: Path.resolve(__dirname, '../src/scripts'),
      StyleFiles: Path.resolve(__dirname, '../src/styles'),
      ImageFiles: Path.resolve(__dirname, '../src/images'),
    }
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: Path.resolve(__dirname, '../src'),
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          emitWarning: true
        }
      },
      {
        test: /\.js$/,
        include: Path.resolve(__dirname, '../src'),
        loader: 'babel-loader'
      },
      {
        test: /\.s?css$/i,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader?sourceMap=true'
          },
          {
            loader: 'sass-loader'
          }
        ],
      },
      {
        test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
        use: {
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]',
          },
        },
      },
    ],
  },
});

webpack.prod.js

const Path = require('path');
const Glob = require('glob');
const Webpack = require('webpack');
const {merge} = require('webpack-merge');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const PurgecssPlugin = require('purgecss-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const common = require('./webpack.common.js');

// Let us use Node JS
const fs = require('fs');

// Get all pages in /src by filtering .twig
const pages = fs.readdirSync(Path.resolve(__dirname, '../src/')).
  filter(fileName => fileName.endsWith('.twig') && fileName !== 'index.twig');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  stats: 'errors-only',
  bail: true,
  output: {
    filename: 'js/bundle-[hash]-[id].js',
    chunkFilename: 'js/bundle-[hash]-[id].chunk.js',
  },
  resolve: {
    alias: {
      'FaviconFiles': Path.resolve(__dirname, '../src/favicon'),
      'ScriptFiles': Path.resolve(__dirname, '../src/scripts'),
      'StyleFiles': Path.resolve(__dirname, '../src/styles'),
      'ImageFiles': Path.resolve(__dirname, '../src/images'),
    },
  },
  module: {
    rules: [
      {
        test: /\.(js)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.s?css/i,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
        use: {
          loader: 'file-loader',
        },
      },
    ],
  },
  plugins: [
    new Webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: Path.resolve(__dirname, '../src/images'), to: 'images',
        },
        {
          from: Path.resolve(__dirname, '../.htaccess'),
        },
        {
          from: Path.resolve(__dirname, '../src/fonts'), to: 'fonts',
        },
        {
          from: Path.resolve(__dirname, '../src/favicon'), to: 'favicon',
        },
      ],
    }),
    ...pages.map(page => new HtmlWebpackPlugin({
      filename: page.replace('twig', 'html'),
      template: Path.resolve(__dirname, ('../src/' + page)),
    })),
    new MiniCssExtractPlugin({
      filename: 'styles/bundle-[hash].css',
    }),
    new PurgecssPlugin({
      whitelistPatterns: [/bullet$/, /bullet-active$/, /collapse$/],
      whitelist: ['collapsing'],
      paths: Glob.sync(`${Path.join(__dirname, '../src')}/**/*`,
        {nodir: true}),
    }),
  ],
});

在构建我的网站时,我想要以下结构:

- dist
  - favicon
  - fonts
  - images
  - js
  - styles
  - index.html
  - .htaccess

为什么它不能识别这些别名?不幸的是,它没有给我任何错误,所以我不知道我做错了什么。

标签: javascriptwebpack

解决方案


推荐阅读