如何写一个最简单的vue-cli(tiny-cli)

这是我参与更文挑战的第2天,活动详情查看: 更文挑战

demo源码
看着代码更容易理解,代码有注释。

仓库说明

base分支

基础的webpack配置,然后webpack运行项目,这边直接将webpack命令通过package.json的scripts去执行了。

npm i
npm run watch
复制代码

base-vue分支

vue项目的webpack的一般配置

npm run dev
复制代码

base-cli分支

基本的cli所拥有的功能,生成项目,开发环境,生产环境是如何运行的。

tiny-cli -i app //创建一个app项目
cd app
npm i
tiny-cli -d //开发环境启动
tiny-cli -b //生产编译
复制代码

template分支

用于创建初始项目时需要clone的项目模板

需要的哪些模块?

做成cli,除了webpack和babel等一些基础的编译配置,还需要

commander,用于创建终端命令,上面的-d,-b等命令就是通过这个来创建的;

download-git-repo,创建项目的时候需要该模块从git上clone基本的项目目录;

chalkora,这两个库是用于编译时美化输出的,为了更好看。

以vue框架为例,基本webpack配置?

详情见源码的base-vue分支
常用配置

  • entry:编译入口,当前项目的主要的js文件,比如当前的 src/index.js;
  • output: 输出配置;
  • module: 一般常用rules,用于编译不同文件的代码,如es,vue文件等,需要使用的vue-loader,babel-loader等;
  • plugins:编译时对某些运行钩子要做的事情;
  • resolve:加快对文件的引用,以及别名的命名等。
const webpack = require('webpack');
const path = require('path');
const CWD = process.cwd();
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    publicPath: '/',
    filename: 'js/[name].[hash].js'
  },
  module: {
    rules: [
      // babel编译
      {
        test: /\.js|jsx$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
      // vue编译loader,需要与下面的plugin的VueLoaderPlugin联合使用,不然会报错
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      // less编译
      {
        test: /\.less$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
          },
        ]
      },
      // 对css样式进行编译,包括vue文件里面的style
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader'],
        }),
      },
      // 加载静态文件, webpack4版本不需要file-loader单独配置,不然图片出不来(巨坑)
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              fallback: require.resolve('file-loader'),
              limit: 8192,
              esModule: false,
            },
          },
        ],
      },
    ],
  },
  plugins:  [
    // 清空之前的输出目录
    new CleanWebpackPlugin(),
    //  以什么html为模板
    new HtmlWebpackPlugin({
      hash: true,
      title: 'tiny-demo',
      template: './src/index.html',
    }),
    new ExtractTextPlugin('style.css'),
    // 与vue-loader配合使用,编译vue文件
    new VueLoaderPlugin(),
    // 启用热替换
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ],
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist',
    hot: true
  },
  // 别名
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js', //这里如果不加这个,import vue时会报错
      '@': path.join(CWD, './src') //src别名目录
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
};
复制代码

如何将tiny-cli命令挂载到本地全局访问?

其实很简单,package.json有个bin配置,将需要运行的nodejs文件配置好即可,如:

  "bin": {
    "tiny-cli": "bin/index.js"
  },
复制代码

这里写好之后,通过npm link就可以将tiny-cli挂载到全局访问,这里其实最终版运行的是bin目录下的index.js文件,最终执行的命令是node bin/index,所有的命令执行将通过bin下面的program文件去判断,当前执行的命令是什么,根据命令的不同通过判断,去做不同的操作,这里只做了三个命令操作,一个创建项目(-i),一个开发环境启动(-d),一个生产编译(-b)。如果要去除这个tiny-cli全局命令,只需要npm unlink即可。

如何执行命令?

主要代码:bin/program.js

运用模块:commander

需要使用commander模块,主要代码在bin/program.js,这里可配置各种不同命令,运行时通过program的对象属性判断,比如,program.dev就是用于判断是否是开发环境

如何生成一个基本的template目录?

主要代码:repo.js

运用模块:download-git-repo

该文件主要处理项目创建时的模板clone,创建时使用了chalk和ora模块,美化了创建时的输出。

最后

等一切测试成功之后,就可以直接运行npm publish 发布到自己的npm账号的packages了。自己对着代码,直接运行看看吧,代码较简单,没有附加功能,有问题直接评论区哦!!谢谢各位观看!!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享