@craco/craco复写cra项目配置

本文介绍了如何使用Craco配置Webpack,包括设置别名以简化导入路径,修改打包产物文件夹名称为dist,配置CDN以在生产环境中引用库,启用Gzip压缩以减小文件大小,以及如何全局引入SCSS文件。同时,还提到了移动端适配的解决方案。
摘要由CSDN通过智能技术生成

路径别名(alias)

const webpackConfig = {
      webpack: {
        alias: {
          '@': path.resolve(__dirname, 'src'), // 配置src别名
        },
    }
}
module.export = webpackConfig

修改打包产物文件夹名称

cra默认打包后的产物文件夹名build,我们习惯性的叫dist

关键的两行必须写:

paths.appBuild = 'dist'

path: path.resolve(__dirname, 'dist')

const webpackConfig = {
    webpack: {
        configure: (webpackConfig, { env, paths }) => {
          paths.appBuild = 'dist' // 修改打包输出文件目录
          webpackConfig.output = {
            ...webpackConfig.output,
            path: path.resolve(__dirname, 'dist'), // 修改打包输出文件目录 两步都要写
            publicPath: whenProd(() => '/', '/'), // 静态资源publicpath
              }
          }
        })
    }
}

生产库引用cdn

cra内置了HtmlWebpackPlugin插件,直接用cra的getPlugin方法获取插件实例即可

const { getPlugin, pluginByName, whenProd } = require('@craco/craco')
const webpackConfig = {
    webpack: {
        configure((config,{env, paths})){
             // 线上替换cdn key:value key为库的名字 value为umd模块导出到global对象的key名
      whenProd(() => {
        webpackConfig.externals = {
          react: 'React',
          'react-dom': 'ReactDOM',
          history: 'History',
          'react-router-dom': 'ReactRouterDOM',
          redux: 'Redux',
          'react-redux': 'ReactRedux',
          dayjs: 'dayjs',
          antd: 'antd',
          axios: 'axios',
          '@ant-design/icons': 'icons',
        }
      })
      // 根据插件名获取插件 返回是否找到和匹配的插件
      const { isFound: isHtmlWebpackPluginFound, match: htmlWebpackPlugin } =
        getPlugin(webpackConfig, pluginByName('HtmlWebpackPlugin'))
      if (isHtmlWebpackPluginFound) {
        htmlWebpackPlugin.userOptions.title = whenProd(
          () => '后台管理系统-生产环境',
          '后台管理系统-开发环境'
        )
        // cdnurl要按照库的相互依赖优先级填写 被依赖的写前面优先加载
        htmlWebpackPlugin.userOptions.cdn = whenProd(
          () => ({
            js: [
              'https://cdn.bootcdn.net/ajax/libs/react/18.2.0/umd/react.production.min.js',
              'https://cdn.jsdelivr.net/npm/react-router-dom@5.3.0/umd/react-router-dom.min.js',
              'https://cdnjs.cloudflare.com/ajax/libs/history/4.9.0/history.min.js',
              'https://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js',
              'https://cdn.bootcdn.net/ajax/libs/redux/4.2.0/redux.min.js',
              'https://cdn.bootcdn.net/ajax/libs/react-redux/8.0.5/react-redux.min.js',
              'https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.7/dayjs.min.js',
              'https://cdn.bootcdn.net/ajax/libs/antd/5.1.6/antd.min.js',
              'https://cdn.bootcdn.net/ajax/libs/axios/1.2.5/axios.min.js',
              'https://cdn.bootcdn.net/ajax/libs/ant-design-icons/5.0.1/index.umd.min.js',
            ],
            css: ['https://cdn.bootcdn.net/ajax/libs/antd/5.1.6/reset.min.css'],
          }),
          // 本地环境设为空 防止页面遍历报错
          {
            js: [],
            css: [],
          }
        )
      }
            return webpackConfig
        }
    }
}
module.exports = webpackConfig;

html模板遍历生成标签: 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <!-- js表达式写在<\%表达式\%> 渲染变量<\%=变量l\%> 这里的\是为了转义百分号防止webpack报错-->
    <% htmlWebpackPlugin.options.cdn.css.forEach(cdnUrl => { %>
    <link rel="stylesheet" href="<%= cdnUrl %>" />
    <% }) %>
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>您的浏览器不支持JavaScript 请开启JavaScript再浏览</noscript>
    <div id="root"></div>
  </body>
  <% htmlWebpackPlugin.options.cdn.js.forEach(cdnUrl => { %>
  <script type="text/javascript" src="<%= cdnUrl %>"></script>
  <% }) %>
</html>

gzip压缩(NGINX要开启gzip解压)

先安装压缩插件compression-webpack-plugin:

yarn add compression-webpack-plugin -D

const CompressionWebpackPlugin = require('compression-webpack-plugin')
const webpackConfig = {
    webpack: {
        configure(webpackConfig, { env, paths }){
          // 使用gzip压缩超过1M的js和css文件
          webpackConfig.plugins.push(
            new CompressionWebpackPlugin({
              algorithm: 'gzip',
              test: /\.(js|css)$/,
              threshold: 1024,
              minRatio: 0.8,
            })
          )
          return webpackConfig
        }
    }
}
module.exports = webpackConfig;

混入全局scss文件

使用插件craco-sass-resources-loader处理全局scss,先安装:

yarn add craco-sass-resources-loader -D

const sassResourcesLoader = require('craco-sass-resources-loader')
const webpackConfig = {
    plugins: [
    {
      plugin: sassResourcesLoader, // 在所有scss文件加载前加载 全局加载到前面
      options: {
        // 配置多个文件 传文件的绝对路径
        resources: [
          path.resolve(__dirname, 'src', 'styles', 'common.module.scss'),
          path.resolve(
            __dirname,
            'src',
            'styles',
            'global-variables.module.scss'
          ),
          path.resolve(__dirname, 'src', 'styles', 'antd.module.scss'),
        ],
      },
    },
  ],
}
module.exports = webpackConfig;

 修改开发服务器端口

const webpackConfig = {
    devServer: {
        port: 8421,
    }
}
module.exports = webpackConfig;

分析打包的js包体积

安装插件source-map-explorer(cra官方文档推荐插件)还有一款彩色的可视化插件:webpack-bundle-analyzer,安装插件

yarn add source-map-explorer -D

package.json配置脚本:

注意: 要开sourcemap,否则执行会报错:export GENERATE_SOURCEMAP=true 加export导出变量到.env.环境文件 默认.env.dev文件环境变量是开启的GENERATE_SOURCEMAP=true

{
    "scripts": {
    "dev": "craco start",
    "build": "craco build",
    "buildServe": "craco build && serve -s dist",
    "analyze": "export GENERATE_SOURCEMAP=true && yarn build && source-map-explorer dist/static/js/*.js"
  },
}

craco.config.js完整代码:

const path = require('path')
const sassResourcesLoader = require('craco-sass-resources-loader')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const { getPlugin, pluginByName, whenProd } = require('@craco/craco')
const config = {
  devServer: {
    port: 8421,
  },
  webpack: {
    alias: {
      'geek-pc': path.resolve(__dirname, 'src'),
    },
    configure: (webpackConfig, { env, paths }) => {
      paths.appBuild = 'dist' // 修改打包输出文件目录
      webpackConfig.output = {
        ...webpackConfig.output,
        path: path.resolve(__dirname, 'dist'), // 修改打包输出文件目录 两步都要写
        publicPath: whenProd(() => '/', '/'), // 静态资源publicpath
      }
      // 线上替换cdn key:value key为库的名字 value为umd模块导出到global对象的key名
      whenProd(() => {
        webpackConfig.externals = {
          react: 'React',
          'react-dom': 'ReactDOM',
          history: 'History',
          'react-router-dom': 'ReactRouterDOM',
          redux: 'Redux',
          'react-redux': 'ReactRedux',
          dayjs: 'dayjs',
          antd: 'antd',
          axios: 'axios',
          '@ant-design/icons': 'icons',
        }
      })
      // 根据插件名获取插件 返回是否找到和匹配的插件
      const { isFound: isHtmlWebpackPluginFound, match: htmlWebpackPlugin } =
        getPlugin(webpackConfig, pluginByName('HtmlWebpackPlugin'))
      if (isHtmlWebpackPluginFound) {
        htmlWebpackPlugin.userOptions.title = whenProd(
          () => '生产环境',
          '开发环境'
        )
        // cdnurl要按照库的相互依赖优先级填写 被依赖的写前面优先加载
        htmlWebpackPlugin.userOptions.cdn = whenProd(
          () => ({
            js: [
              'https://cdn.bootcdn.net/ajax/libs/react/18.2.0/umd/react.production.min.js',
              'https://cdn.jsdelivr.net/npm/react-router-dom@5.3.0/umd/react-router-dom.min.js',
              'https://cdnjs.cloudflare.com/ajax/libs/history/4.9.0/history.min.js',
              'https://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js',
              'https://cdn.bootcdn.net/ajax/libs/redux/4.2.0/redux.min.js',
              'https://cdn.bootcdn.net/ajax/libs/react-redux/8.0.5/react-redux.min.js',
              'https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.7/dayjs.min.js',
              'https://cdn.bootcdn.net/ajax/libs/antd/5.1.6/antd.min.js',
              'https://cdn.bootcdn.net/ajax/libs/axios/1.2.5/axios.min.js',
              'https://cdn.bootcdn.net/ajax/libs/ant-design-icons/5.0.1/index.umd.min.js',
            ],
            css: ['https://cdn.bootcdn.net/ajax/libs/antd/5.1.6/reset.min.css'],
          }),
          // 本地环境设为空 防止页面遍历报错
          {
            js: [],
            css: [],
          }
        )
      }
      // 使用gzip压缩超过1M的js和css文件
      webpackConfig.plugins.push(
        new CompressionWebpackPlugin({
          algorithm: 'gzip',
          test: /\.(js|css)$/,
          threshold: 1024,
          minRatio: 0.8,
        })
      )
      return webpackConfig
    },
  },
  plugins: [
    {
      plugin: sassResourcesLoader, // 在所有scss文件加载前加载 全局加载到前面
      options: {
        // 配置多个文件 传文件的绝对路径
        resources: [
          path.resolve(__dirname, 'src', 'styles', 'common.module.scss'),
          path.resolve(
            __dirname,
            'src',
            'styles',
            'global-variables.module.scss'
          ),
          path.resolve(__dirname, 'src', 'styles', 'antd.module.scss'),
        ],
      },
    },
  ],
}
module.exports = config

移动端适配

yarn add postcss-px-to-viewport-8-plugin -D

const PostCssPxToViewportPlugin = require('postcss-px-to-viewport-8-plugin') // 针对postcss8.x版本生效的插件
module.exports = {
  style: {
    postcss: {
      mode: 'extends',
      loaderOptions: {
        postcssOptions: {
          ident: 'postcss',
          plugins: [
            'postcss-px-to-viewport-8-plugin',
            PostCssPxToViewportPlugin({
              viewportWidth: 375, // 视口宽度
              viewportUnit: 'vmin', // px转换后的单位
              fontViewportUnit: 'vmin', // 字体转换后的单位
            }),
          ],
        },
      },
    },
  },
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值