【问题标题】:How can Webpack 5 polyfills resolve with Yarn 2 PnP? (Cypress issue)Webpack 5 polyfills 如何使用 Yarn 2 PnP 解决? (柏树问题)
【发布时间】:2020-12-06 16:08:17
【问题描述】:

我在将 cypress-dark(主题)插件添加到 Yarn 2 工作区的“测试”包中时遇到了这个问题,但我认为这个问题很普遍。为了更详细地说明最初的问题,我认为我需要知道的是:如何获得 Webpack 的 resolve.fallback 选项以使用 PnPWebpackPlugin?

为了在 Cypress 中使用 Webpack 5,我一直在使用 cypress-webpack-preprocessor-v5。在 support/index.ts 中导入 cypress-dark 后,在浏览器中运行规范会产生以下错误:

Error: Webpack CompLooked for and couldn't find the file at the following paths:resolve 'path' in '/home/john/Projects/current/djinndex-remastered/.yarn/cache/postcss-npm-7.0.16-2507f8c3e2-b867411523.zip/node_modules/postcss/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
    - install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "path": false }

所以我加了

resolveLoader: {
        plugins: [PnpWebpackPlugin.moduleLoader(module)],
},

到我的 plugins/index.ts 如下:

/**
 * @type {Cypress.PluginConfig}
 */
//@ts-ignore
module.exports = (on, config) => {
  // `on` is used to hook into various events Cypress emits
  // `config` is the resolved Cypress config
  const options = {
    webpackOptions: {
      ...require('../../../client/webpack/webpack.cypress.js'),
      resolve: {
        plugins: [PnpWebpackPlugin],
        extensions: ['.ts', '.js'],
        fallback: { path: require.resolve('path-browserify') },
      },
      resolveLoader: {
        plugins: [PnpWebpackPlugin.moduleLoader(module)],
      },
      module: {
        rules: [
          {
            test: /\.ts$/,
            exclude: [/node_modules/],
            use: [
              {
                loader: 'ts-loader',
              },
            ],
          },
        ],
      },
    },
    watchOptions: {},
  };
  on('file:preprocessor', webpackPreprocessor(options));
};

运行规范会产生以下错误:

cypress_runner.js:199777 AssertionError: Timed out retrying: `cy.readFile("dark.css")` failed because the file does not exist at the following path:

`/home/[.../<workspace>/]packages/test/dark.css`

Because this error occurred during a `before all` hook we are skipping all of the remaining tests.
    at Context.eval (http://localhost:3000/__cypress/tests?p=cypress/support/index.ts:3280:8)

Webpack 应该在来自 /.yarn/cache/cypress-dark-npm-1.7.14-295ea64c64-9b608eccac.zip 的 Yarn 2 虚拟包中查找 dark.css,而不是在“测试”的根目录中我正在运行赛普拉斯的(工作区的)包。所以看起来像

{resolve: fallback: { path: require.resolve('path-browserify')} 

在 webpackOptions 中回退到不知道 PnPWebpackPlugin 的解决方案。这就是我卡住的地方。任何指导将不胜感激:)

【问题讨论】:

    标签: webpack cypress yarn-workspaces webpack-5 yarnpkg-v2


    【解决方案1】:

    事实证明,Webpack 5 的路径 polyfill 在 Yarn 2 上运行良好。问题是包本身 cypress-dark 专门寻找 node_modules 目录:

    ? join('node_modules/cypress-dark/src')
    

    所以,这是个好消息。对于其他 Yarn 2 用户,为了避免 node_modules 的事情,我最终只是在 cypress/support/theme/index.ts 本地重新创建了一个简化版本的 cypress-dark 插件:

    import postcss from 'postcss';
    //@ts-ignore
    import cssVariables from 'postcss-css-variables';
    
    const getHead = () => Cypress.$(parent.window.document.head);
    const $head = getHead();
    const isStyleLoaded = ($head: JQuery<HTMLHeadElement>) =>
      $head.find('#cypress-dark').length > 0;
    
    const convertCssVariables = (mycss: any) =>
      postcss([cssVariables()]).process(mycss).css;
    
    export const loadTheme = (theme: string) => {
      return () => {
        const $head = getHead();
        if (isStyleLoaded($head)) {
          return;
        }
    
        const themeFilename = `${theme}.css`;
    
        cy.readFile(themeFilename, { log: false })
          .then(convertCssVariables)
          .then((css) => {
            $head.append(
              `<style type="text/css" id="cypress-dark" theme="${theme}">\n${css}</style>`
            );
          });
      };
    };
    

    我将 dark.css 复制到 cypress/support/theme(并进行了一些个人偏好调整)。然后我在 cypress/support/index.ts 中调用了 loadTheme("dark"):

    import { loadTheme } from './theme';
    before(loadTheme('dark'));
    

    【讨论】:

      猜你喜欢
      • 2020-05-17
      • 2020-06-25
      • 2021-12-22
      • 2021-04-12
      • 2021-02-15
      • 2019-05-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      相关资源
      最近更新 更多