CodeMirror:Uncaught TypeError codeMirrorInstance.fromTextArea is not a function

之前在《CodeMirror实现关键词高亮及自定义主题》中简单介绍过react-codeMirror的使用和主题的自定义方式,最近在另外一个webpack打包的React项目中再次使用时遇到题目中比较奇怪的问题,请教了两位同事,终于解决了该问题,特此记录一下排查问题的过程及导致问题的原因。

首先说明一下问题,在组件中使用最简单的方式使用react-codeMirror,代码示例如下:

import React from 'react'
import CodeMirror from 'react-codemirror';
import 'codemirror/mode/sql/sql';
import 'codemirror/mode/javascript/javascript.js';
import 'codemirror/lib/codemirror.css';
import ReactDOM from "react-dom";

export default class CodemirrorTest extends React.Component{
    constructor(props){
        super(props);
        this.state = {};
        this.options = {
            lineNumbers: true
        };
      }
    handleChange(code){
        console.warn(code);
    }
    render(){
        return(
            <CodeMirror 
                ref={ref => this.codeComponent = ref} 
                value={'test'} 
                onChange={this.handleChange} 
                options={this.options}
            />
        )
    }
}
ReactDOM.render(<CodemirrorTest />, document.getElementById('container'));

 当渲染该组件时,会出现如下错误:

 可以看到错误原因是:

在Codemirror.js文件中componentDidMount周期会通过调用getCodeMirrorInstance方法获取codemirror的instance,出现Uncaught TypeError codeMirrorInstance.fromTextArea is not a function的错误肯定是getCodeMirrorInstance方法没有正常返回,并没有提示undefined相关。

看到这里,比较简单的一种解决方式就已经出现了,getCodeMirrorInstance方法没有正常返回肯定是require('codemirror')执行有问题,因为我们没有通过props传递codeMirrorInstance,所以比较简单的方式就是:

import React from 'react'
import CodeMirror from 'react-codemirror';
import 'codemirror/mode/sql/sql';
import 'codemirror/mode/javascript/javascript.js';
import 'codemirror/lib/codemirror.css';
import ReactDOM from "react-dom";

export default class CodemirrorTest extends React.Component{
    constructor(props){
        super(props);
        this.state = {};
        this.options = {
            lineNumbers: true
        };
        this._codeMirrorInstance = require('codemirror');
    }
    handleChange(code){
        console.warn(code);
    }
    render(){
        return(
            <CodeMirror
                ref={ref => this.codeComponent = ref}
                value={'test'}
                onChange={this.handleChange}
                options={this.options}
                codeMirrorInstance={this._codeMirrorInstance}
            />
        )
    }
}
ReactDOM.render(<CodemirrorTest />, document.getElementById('container'));

 经过测试,这样已经可以解决问题。但是,依然不知道导致问题的原因是什么。

 要找到问题的原因,就要确认getCodeMirrorInstance方法返回的到底是什么,通过在

getCodeMirrorInstance中console.log 相关信息,我们发现,getCodeMirrorInstance返回的竟然是react-codemirror自己,这里比较奇怪的是codemirror的文件命名为,而react-codemirror的主文件命名为Codemirros.js,结合webpack编译时的warning:

 

 猜想应该是module名称有冲突,所以猜测是打包过程中require的module有问题。

下面就是查webpack文件,终于发现如下配置:

 

 modules的查找会先从自己的目录开始,而windows对大小写不敏感(Codemirror,codemirror),所以就导致了题目中问题的产生。

比较方便的解决方式为在resolve中给codemirror加一个别名:

 至此,Uncaught TypeError codeMirrorInstance.fromTextArea is not a function的问题已经解决,出现该问题的原因也比较清楚了。

总结如下:

出现Uncaught TypeError codeMirrorInstance.fromTextArea is not a function的原因:

  1. resolve模块时本目录优先;
  2. react-codemirror和codemirror的文件命名(Codemirror,codemirror);
  3. 编译时对大小写不敏感。

碰到此问题的解决方法:

  1. 在组件中先require codemirror,通过props传递给react-codemirror;

resolve加别名。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值