xccjk / x-blog

学习笔记
17 stars 2 forks source link

webpack相关 #85

Open xccjk opened 1 year ago

xccjk commented 1 year ago

使用import styles from './index.less'导入less时,styles报错

webpack.config.js

const webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: {
    detail: './src/detail/index.js',
  },
  output: {
    path: path.resolve(__dirname, './public/static/js'),
    filename: '[name].js',
  },
  mode: 'development',
  module: {
    rules: [
      ...
      {
        test: /\.less$/,
        exclude: /node_modules/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
          },
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                javascriptEnabled: true,
              },
            },
          },
        ],
      },
    ],
  },
};

app.js

import React from 'react';
import styles from './index.less';

const BlockDetail = () => {
  return (
    <div className={styles.container}>
      <div className={styles.txt}>detail</div>
    </div>
  );
};

export default BlockDetail;

此时跑起项目后,会报错:

Uncaught TypeError: Cannot read properties of undefined (reading 'container')

正确使用方式:修改css-loader options modules为true

{
  loader: 'css-loader',
  options: {
    modules: true,
  },
},
xccjk commented 1 year ago

css-loader options modules为true时,antd样式失效

当webpack配置了css-loader options modules为true时,会发现通过import导入的antd样式失效了

app.js

import React from 'react';
import { Input } from 'antd';
import 'antd/dist/antd.less';
import styles from './index.less';

const App = () => {
  return (
    <div className={styles.container}>
      <Input />
      <div className={styles.txt}>detail</div>
    </div>
  );
};

export default App;

问题原因:项目中样式采用css modules的写法,构建之后会被重命名。如果项目中引入了antd的样式,则会导致样式加载不到问题

当遇到这种情况时,有下列两种解决方案:

  1. 在打包后的html文件中引入antd.css文件,不过这样就做不到样式的按需加载了
  2. 只针对业务代码中的样式开启css module modules为true

如果是全局引入的antd.css文件

import 'antd/dist/antd.css';

此时webpack配置:

{
  test: /\.css$/,
  // 针对node_modules中的文件,不开启css modules
  exclude: /src/,
  use: [
    {
      loader: 'style-loader',
      options: {
        singleton: true,
      },
    },
    {
      loader: 'css-loader',
    },
    {
      loader: 'postcss-loader',
    },
  ],
},
{
  test: /\.css$/,
  exclude: /node_modules/,
  use: [
    {
      loader: 'style-loader',
      options: {
        singleton: true,
      },
    },
    {
      loader: 'css-loader',
      options: {
        modules: true,
      },
    },
    {
      loader: 'postcss-loader',
    },
  ],
 },

如果是全局引入antd.less文件

import 'antd/dist/antd.less';

此时webpack配置

{
  test: /\.less$/,
  exclude: /src/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
    },
    {
      loader: 'postcss-loader',
      options: {
        postcssOptions: {
          plugins: [require('autoprefixer')],
        },
      },
    },
    {
      loader: 'less-loader',
      options: {
        lessOptions: {
          javascriptEnabled: true,
        },
      },
    },
  ],
},
{
  test: /\.less$/,
  exclude: /node_modules/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        modules: true,
      },
    },
    {
      loader: 'postcss-loader',
      options: {
        postcssOptions: {
          plugins: [require('autoprefixer')],
        },
      },
    },
    {
      loader: 'less-loader',
      options: {
        lessOptions: {
          javascriptEnabled: true,
        },
      },
    },
  ],
},

这样配置后,在业务中既可以使用import styles from 'xxx'的语法,也不会导致antd的样式失效了

xccjk commented 1 year ago

webpack打包vue

报错export 'default' (imported as 'Vue') was not found in 'vue'

https://blog.csdn.net/angelia620/article/details/121278156

webpack配置文件后运行报错TypeError: VueLoaderPlugin is not a constructor

老版本:

const VueLoaderPlugin = require('vue-loader/lib/plugin')

新版本:

const { VueLoaderPlugin } = require('vue-loader')
xccjk commented 1 year ago

webpack5升级过程遇到的一些坑

版本相关信息

  "webpack": "^5.10.3",
  "webpack-cli": "^4.2.0",
  "webpack-dev-server": "^3.11.0"
  // .babelrc.js
  module.exports = {
    presets: [
      [
        '@babel/preset-env',
        {
          targets: {
            browsers: ['> 5%', 'IE 10', 'iOS 7', 'Firefox > 20']
          },
          useBuiltIns: 'usage',
          corejs: 3
        }
      ],
      '@babel/preset-react'
    ],
    plugins: [
      '@babel/plugin-transform-runtime',
      '@babel/plugin-proposal-class-properties',
      [
        'import',
        {
          libraryName: 'antd',
          libraryDirectory: 'es'
        }
      ]
    ]
  }

问题

  1. Error: Cannot find module 'webpack-cli/bin/config-yargs'

webpack-cli 4.x中,不能过webpack-dev-server启动项目了,需要通过webpack serve...或者修改webpack-cli版本改为3.x

  // package.json
  // webpack4.x
  "script": {
    "dev": "webpack-dev-server ...",
  }
  // webpack5.x
  "script": {
    "dev": "webpack serve ...",
  }
  // 降版本
  {
    webpack-cli@3.3.12
  }
  1. webpack5中错误出现错误UnhandledPromiseRejectionWarning: TypeError: webpack.NamedModulesPlugin is not a constructor
  // webpack.config.js

  // webpack4.x
  module.exports = {
    ...
    plugins: [
      ...
      new webpack.NamedModulesPlugin()
    ]
  }

  // webpack5.x
  // 在webpack5.x中,webpack.NamedModulesPlugin的功能已经内置
  1. babel配置导致的文件引入错误,@babel/runtime

在webpack5.x中,发现很多关于@babel/runtime/helpers/esm的文件引入错误,错误提示类似下面,通过锁定@babel/runtime包版本即可

Module not found: Error: Can't resolve './superPropBase' in '/Users/xxx/node_modules/@babel/runtime/helpers/esm'
Did you mean 'superPropBase.js'?
BREAKING CHANGE: The request './superPropBase' failed to resolve only because it was resolved as fully specified
(probably because the origin is a '*.mjs' file or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request
  npm install @babel/runtime@7.12.0 -D
  1. webpack < 5 used to include polyfills for node.js core modules by default

在运行过程中出现了很多这样的报错信息,是由于在webpack5中移除了nodejs核心模块的polyfill自动引入,所以需要手动引入,如果打包过程中有使用到nodejs核心模块,webpack会提示进行相应配置

  // webpack.config.js
  module.exports = {
    ...
    resolve: {
      // https://github.com/babel/babel/issues/8462
      // https://blog.csdn.net/qq_39807732/article/details/110089893
      // 如果确认需要node polyfill,设置resolve.fallback安装对应的依赖
      fallback: {
        crypto: require.resolve('crypto-browserify'),
        path: require.resolve('path-browserify'),
        url: require.resolve('url'),
        buffer: require.resolve('buffer/'),
        util: require.resolve('util/'),
        stream: require.resolve('stream-browserify/'),
        vm: require.resolve('vm-browserify')
      },
      // 如果确认不需要node polyfill,设置resolve.alias设置为false
      alias: {
        crypto: false
      }
    }
  }
  1. DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated. BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation. Do changes to assets earlier, e. g. in Compilation.hooks.processAssets. Mak`e sure to select an appropriate stage from Compilation.PROCESS_ASSETSSTAGE*.

html-webpack-plugin这个包导致的⚠️信息,github issue

  npm run html-webpack-plugin@next -D
  1. DeprecationWarning: A 'callback' argument need to be provided to the 'webpack(options, callback)' function when the 'watch' option is set. There is no way to handle the 'watch' option without a callback

官方给出的问题原因是webpack-cli这个包的版本导致的,github issue

  // 官方提供的解决方式,修改webpack-cli版本到4.2.0既可
  npm install webpack-cli@4.2.0 --save-dev

不过我在本地创建了一个新的项目,版本信息如下,还是存在上面的那个报错信息,demo地址github issue

  "webpack": "^5.10.3",
  "webpack-cli": "^4.2.0",
  "webpack-dev-server": "^3.11.0"
  1. 业务插件遇到的问题,webpack-merge包遇到的问题

csdn资料

  // 4.x版本
  {
    "webpack-merge": "^4.2.2"
  }
  // webpack.config.js
  const merge = require('webpack-merge')
  const defaultConfig = require('../...')
  const config = merge(defaultConfig, {

  })
  export default config

  // 5.x版本
  {
    "webpack-merge": "^5.7.0"
  }
  const webpackMerge = require('webpack-merge')
  const defaultConfig = require('../...')
  const config = webpackMerge.merge(defaultConfig, {

  })
  export default config
  1. 数据流工具recoil好像还不支持在webpack中使用,我们项目里有使用recoil,配置了babel后,一直提示You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

官方答复:guthub issue

  1. TypeError: Cannot read property 'tap' of undefined

hard-source-webpack-plugin这个包在版本升级后出现错误,github issue

  // webpack.config.js
  // webpack4.x
  const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
  module.exports = {
    ...
    piugins: [
      new HardSourceWebpackPlugin({
        environmentHash: {
          root: process.cwd(),
          directories: [],
          files: ['package-lock.json', 'yarn.lock'],
        },
        cachePrune: {
          maxAge: 2 * 24 * 60 * 60 * 1000,
          sizeThreshold: 50 * 1024 * 1024
        }
      })
    ]
  }
  // webpack5.x
  // https://github.com/mzgoddard/hard-source-webpack-plugin/issues/461
  const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
  module.exports = {
    ...
    piugins: [
      new HardSourceWebpackPlugin(),
      new HardSourceWebpackPlugin.ExcludeModulePlugin([])
    ]
  }

webpack升级日志

xccjk commented 1 year ago

umi3 优化lodash体积

yarn add lodash-webpack-plugin

config.js

import { defineConfig } from 'umi';
import LodashModuleReplacementPlugin from 'lodash-webpack-plugin';

export default defineConfig({
  ...
  chainWebpack(config) {
    config.plugin('lodash-webpack-plugin').use(
      new LodashModuleReplacementPlugin({
        collections: true,
        paths: true,
      }),
    );
  })
})
xccjk commented 1 year ago

lodash-webpack-plugin iteratee 不是函数

new LodashModuleReplacementPlugin({
  collections: true,
  paths: true,
  shorthands: true
})

issue