Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack相关 #85

Open
xccjk opened this issue Nov 22, 2022 · 5 comments
Open

webpack相关 #85

xccjk opened this issue Nov 22, 2022 · 5 comments

Comments

@xccjk
Copy link
Owner

xccjk commented Nov 22, 2022

使用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
Copy link
Owner Author

xccjk commented Nov 22, 2022

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
Copy link
Owner Author

xccjk commented Nov 22, 2022

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 xccjk changed the title webpack相关问题 webpack相关 Jan 5, 2023
@xccjk
Copy link
Owner Author

xccjk commented Jan 5, 2023

webpack5升级过程遇到的一些坑

版本相关信息

  • node: v14.15.0
  • npm: 6.14.8
  • mac: 10.14.6
  • webpack: 5.10.3
  • webpack-cli: 4.2.0
  • webpack-dev-server: 3.11.0
  "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_ASSETS_STAGE_*.

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
Copy link
Owner Author

xccjk commented Apr 14, 2023

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
Copy link
Owner Author

xccjk commented Apr 14, 2023

lodash-webpack-plugin iteratee 不是函数

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

issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant