HuJiaoHJ/blog

Tips

Opened this issue · 8 comments

Tips

webpack production 打包问题排查及解决

将项目依赖的npm包版本固化之后,webpack production 打包就出现如下问题:

errors xxx.js from uglifyjs 
undefined

可以发现,详细的错误信息为undefined,这个时候需要配置 uglifyjs-webpack-plugin 插件的 parallel 选项为false,即可显示详细错误信息,配置如下:

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
  //...
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
           parallel: false
      })
    ]
  }
}

配置之后,重新打包,错误信息如下:

errors xxx.js from uglifyjs 
TypeError: sym.definition is not a function

解决此问题:https://github.com/fabiosantoscode/terser#replacing-uglify-es-with-terser-in-a-project-using-yarn ,需在 package.json 中添加如下配置:

"resolutions": {
    "uglify-es": "npm:terser"
}

重新安装依赖、打包,问题就解决了

当然,webpack打包问题肯定不都是这个问题,这个tip重点是通过配置将详细的错误信息展示出来,方便问题排查

webpack tree-shaking 不生效

原因

babel会把 ES6 Module 转换成 commonjs 模块(参考:https://babeljs.io/docs/en/babel-preset-env#modules

而webpack本身是依赖 ES6 Module 语法来做 tree-shaking(参考:https://webpack.js.org/guides/tree-shaking/#src/components/Sidebar/Sidebar.jsx)

所以babel默认的配置会导致webpack tree-shaking失效

解决

将 babel preset 配置修改如下:

{
  presets: [
    [
      '@babel/preset-env', 
      {
        'modules': false,
      }
    ]
  ],
}

css modules 动画(Animation)编译问题

@keyframes marquee {
    from {
        transform: translateX(0);
    }
    to {
        transform: translateX(-430px);
    }
}

.marquee {
    animation: 2s marquee linear infinite;
}

使用以上代码,用户不生效,原因是时间写在动画名称之前不识别,需要做如下调整:

.marquee {
    animation: marquee 2s linear infinite;
}

怎么声明全局@Keyframes

@keyframes :global(marquee) {
    from {
        transform: translateX(0);
    }
    to {
        transform: translateX(-430px);
    }
}

React Native 高阶组件编译过程中报:Duplicate declaration "xxx" 错误

高阶组件代码如下:

export default function createIconSet(svgs, fontName) {
  class Icon extends Component {
    ...
  }
  return Icon
}

以上写法会报错,需要做如下修改:

export default function createIconSet(svgs, fontName) {
  return class Icon extends Component {
    ...
  }
}

将写法修改之后能解决问题,但是react-native(0.55.4)中animation组件也是用了上面那种高阶组件的写法,所以不能从写法上解决问题,需要看看是否是babel编译问题

通过排查,确实是babel版本升级问题,从 7.0.0-rc.1 -> 7.0.0-rc.2 ,解决方法则是将babel相关包版本回退到 7.0.0-rc.1

并且babel刚发布的7.0版本也已不支持第一种写法,所以如果需要支持,需使用 7.0.0-rc.1 版本

关于React高阶组件,可以查看:https://reactjs.org/docs/higher-order-components.html

webpack构建中使用postcss插件autoprefixer

因为webpack内置autoprefixer,有默认browserslist配置(而此配置并不能满足实际需求),所以需要自定义配置browserslist

为了项目中自定义browserslist配置生效,需要将browserslist放在package.json中,如下:

{
    ...
    "browserslist": [
        "last 4 versions",
        ">1%",
        "Firefox ESR",
        "iOS 8",
        "not ie < 9"
    ]
}

以上配置保证css兼容Android4.4、IOS 8以上

H5 原生<select>组件导致 iOS UIWebview crash 问题

复现方法:在页面中使用原生<select>组件,且不设置选项<option>

package.json 中 main、module 字段

main 和 module 字段都是定义模块的入口文件的,它们的区别如下:

main

main字段指向 commonjs 模块的入口,使用 require 语法引入

module

module字段指向 ES2015 模块的入口,使用 import 语法引入,支持webpack等构建工具的 tree shaking 优化

dependencies、devDependencies、peerDependencies

  • dependencies:项目运行时所依赖的模块
  • devDependencies:项目开发时所依赖的模块
  • peerDependencies:这是“同伴依赖”,一种特殊的依赖,在发布包的时候需要。有这种依赖意味着安装包的用户也需要和包同样的依赖。(在安装包时会提示)