最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • webpack搭建React项目(6)

    正文概述 掘金(0²)   2021-01-09   430

    resolve

    webpack 的底层配置项resolve主要和模块解析的路径相关,常见的例如mainFilesextensions

    resolve.alias

    配置模块依赖别名,常见的@解析到src文件夹,path.resolve本身是用来构造绝对路径的,所以@总能解析到src目录的路径

    module.exports = {
      resolve: {
        alias: {
          '@': path.resolve(__dirname, './src'),
        },
      },
    };
    

    resolve.enforceExtension

    引入模块必须添加拓展名,默认是false

    resolve.extensions

    配置文件依赖后缀名

    使用resolve.extensions可以配置文件的默认后缀名,默认是['.wasm', '.mjs', '.js', '.json']。当省略文件后缀名时,webpack 会尝试对文件名依次添加后缀名并解析,如果找到相关后缀的文件就停止解析。例如import "./data",那么 webpack 首先会去找文件夹是否存在./data.wasm的文件,找不到就换下一个后缀名./data.mjs,就这样依次解析,如果最后都找不到就会报错。

    需要注意的是默认的配置项不要删除,否则会发生错误,现在在默认配置的基础上加上jsx,即:

    module.exports = {
      resolve: {
        extensions: ['.wasm', '.mjs', '.js', '.json', 'jsx'],
      },
    };
    

    下面是 CRA 内置的解析顺序是这样的:

    const moduleFileExtensions = [
      'web.mjs',
      'mjs',
      'web.js',
      'js',
      'web.ts',
      'ts',
      'web.tsx',
      'tsx',
      'json',
      'web.jsx',
      'jsx',
    ];
    

    resolve.mainFiles

    解析目录时要使用的文件名,默认是['index'],我在 webpack V4.44.1 的版本使用中发现单纯使用这个配置项并不会让 webpack 去自动解析文件夹下的index命名的文件,然后我在 stackoverflow 上发现了这个问题的回答 —— webpack can't find module if file named jsx,对于从 webpack 4.36.1 起,还需要在babel-loader中去配置rule.resolve.extensions,并且这个配置项是决定性的,必须加上rule.resolve.extensions的配置才会让 webpack 自动解析文件夹的index文件,并且".js"也不能省略,否则 react fast refresh 会报错。

    module.exports = {
      module: {
        rules: [
          {
            test: /\.m?jsx?$/,
            exclude: /(node_modules)/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: [
                  [
                    '@babel/preset-env',
                    {
                      modules: false,
                    },
                  ],
                  ['@babel/preset-react'],
                ],
                plugins: [
                  '@babel/plugin-proposal-class-properties',
                  isDevelopment && require.resolve('react-refresh/babel'),
                ].filter(Boolean),
              },
            },
            resolve: { extensions: ['.js', '.jsx'] }, //必须加上这个配置
          },
        ],
      },
    };
    

    resolve.mainFields

    resolve.mainFields针对的是使用第三方库的代码如何进行解析,因为 JS 可以编写在浏览器中使用的代码,也可以编写使用在 nodejs 中的代码,或者一些通用的在服务端和浏览器都可以使用的代码。有的第三方库会针对不同的环境提供几份打包代码放在一起打包,它们会在package.json文件中指定不同环境代码的入口,例如:

    {
      "browser": "build/upstream.js",
      "module": "index"
    }
    

    一般情况下,在搭建项目的时候,会通过 webpack 的配置项 target来指定 webpack 去指定当前项目运行在什么样的环境中,例如target: 'node'指定当前代码最终运行在 nodejs 环境下。具体见 —— target

    当 webpack 的target属性设置成 webworker, web 或者没有指定的时候,那么mainFields的默认值就是['browser', 'module', 'main'],也就是 webpack 会最优先选择browser属性作为入口去解析第三方库的代码,对应上文说的package.json里面提供的"browser"属性的字段值。

    而对于其它指定的target的属性值,例如node等,mainFields的默认值都是['module', 'main']

    resolve.modules

    告诉 webpack 解析模块时应该搜索的目录,默认是['node_modules']。webpack 通过路径解析解析模块的时候会首先查找项目根目录的./node_modules文件夹去寻找模块,如果找不到就往上一级目录 ../node_modules 中去找。

    有时候这个配置比alias还简洁,比方说对于项目中封装通用业务组件库位于src/components下面,然后通过resolve.modules配置模块解析规则如下

    module.exports = {
      resolve: {
        modules: [path.resolve(__dirname, './src/components'), 'node_modules'],
      },
    };
    

    这时候在编写页面的时候,如果import一个src/components下里面的组件,就不用带任何路径前缀直接写文件夹就行了,nice!不过这时候的弊端就是如果你的组件和第三方库的组件同名,就会把第三方库的组件覆盖掉了。

    import { Button } from 'Button/index.jsx';
    

    这个配置加上上文提到的rule.resolve.extensions,结合在一起就是神器,对于src/components的组件,例如src/components/Button,直接一句话就搞定,webpack 会自动查找src/components/Button文件夹下的index文件。

    import { Button } from 'Button';
    

    resolve.plugins

    定义解析模块过程中使用的插件,常用的应该是pnp-webpack-plugin。这个理要了解一下yarn pnp,简单来说Plug'n'Play是替代node_modules依赖机制的方案,对于一个简单项目来说,如果使用 pnp 替代 npm 的机制,可以通过在package.json中配置即可,对于 webpack 项目可以使用插件来支持 pnp 的模块解析机制。例如,CRS 内部就是使用了pnp-webpack-plugin这个插件。

    yarn add pnp-webpack-plugin -D
    
    const PnpWebpackPlugin = require('pnp-webpack-plugin');
    
    module.exports = {
      resolve: {
        plugins: [PnpWebpackPlugin],
      },
      resolveLoader: {
        plugins: [PnpWebpackPlugin.moduleLoader(module)],
      },
    };
    

    CRA 还使用了一个插件,是react-dev-utils/ModuleScopePlugin,这个插件的作用是阻止项目内部从src或者node_modules以外的地方引入模块,因为这通常会引起混乱。一般来说项目代码都会放在src中,一般也不会瞎搞随便引用外面的文件夹。

    resolveLoader

    resolveLoader的配置项和resolve相同,不过resolveLoader只用于解析特定的 loader 模块,例如resolveLoader.moduleExtensions默认是['-loader'],也就是解析 loader 的时候,默认会自动添加-loader的后缀名。

    module.rule.resolve

    module.rule.resolve在上文提到过,也就是在解析特定类型的模块时使用的解析规则,如上文所说,它对于解析index命名的模块是必须配置的项。

    也可以使用上述的resolve的其他配置项,这些配置项会和顶层的resolve配置项进行合并。


    起源地下载网 » webpack搭建React项目(6)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元