为什么 fs.mkdirSync is not a function?

1,122 阅读1分钟

一、前言

Vue 项目

二、问题描述

今天想改进下element的按需导入,写一遍组件名即可,下面是具体代码

// plugins/element/generate.js
const path = require("path");
const fileSave = require("file-save");

const elementList = [
    "DatePicker",
    "Upload",
    "Select",
    "Option",
    "Input",
    "Button",
];

const content = `
import Vue from 'vue';
import 'element-ui/lib/theme-chalk/index.css';
import { 
    ${elementList.join(",\n    ")}
} from 'element-ui'

${elementList.map(item => {
    return `Vue.use(${item})`
}).join('\n')}
`;

fileSave(path.join(__dirname, "./index.js"))
    .write(content, 'utf8')
    .end('\n')
    .error(() => {
        console.log("err")
    })

main.js中引入该文件,浏览器运行项目,发现下面的问题

image.png

然后,找到node_modules/file-save/index.js(入口文件),排查过后发现是savefs._create_dir(dir_path, opts)出现问题,接着来看它的具体实现

savefs._create_dir = function (fp, opts) {
  mkdirp.sync(fp, opts);
}

mkdirp是什么呢?在浏览器中打开它的具体内容

image.png

这里我的opts是没有传的,也就是undefined,如此,xfs就是node.js中内置的fs,既然说xfs.mkdirSync is not a function,在plugins/element/generate.js中引入fs并打印

image.png

fs是空的对象,自然fs.mkdirSync is not a function

三、为什么呢?(百度~)

node.js 是什么?是运行在服务端的JavaScript,而fs是node.js操作文件系统api,不能在项目运行的浏览器中直接使用,可以写成一个命令,执行。

// package.json
{
    ...,
    "scripts": {
        ...,
        "nodeel": "node ./src/plugins/element/data.js",
    },
    ...
}

在终端执行yarn nodeel,便生成了plugins/element/index.js文件

import Vue from 'vue';
import 'element-ui/lib/theme-chalk/index.css';
import { 
    DatePicker,
    Upload,
    Select,
    Option,
    Input,
    Button
} from 'element-ui'

Vue.use(DatePicker)
Vue.use(Upload)
Vue.use(Select)
Vue.use(Option)
Vue.use(Input)
Vue.use(Button)

四、总结

(1)fs 在浏览器中不可使用, path 可以;

(2)遇到 xxx.ccc is not a function 类似报错,先打印 console.log(xxx),看这个对象是否是空的,是否含有ccc这个键.