• 技术文章 >web前端 >Vue.js

    手把手教你使用webpack实现vue-cli

    青灯夜游青灯夜游2022-10-08 18:04:57转载555

    大前端成长进阶课程:进入学习

    当我们刚开始学习vue的时候我们都是使用vue-cli来搭建一个基础的vue项目的基础目录结构,并且实现使用npm run serve,启动我们的vue项目并在本地跑一个8080端口的服务,并且当我们修改并保存时,本地的端口页面也会随之刷新,类似于live-server的功能。【相关推荐:vuejs视频教程

    前言

    要想实现一个vue-cli的脚手架,我们先要了解什么是webpack?如何使用webpack?

    1.png

    本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler) 。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph) ,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。其中包括四个核心概念:

    接下来,我们一边来实现vue-cli给我们搭建的基础结构,一边来简单说一说webpack的核心概念。

    vue-cli实现过程

    首先我们打开一个文件夹,在当前文件夹下打开终端,首先在终端运行npm init -y,使得当前文件下具备package.json的文件,这样我们的这个项目就可以从(node库 (npmjs.com))里去安装我们所需要的依赖,首先我们去使用终端安装 webpack 和 webpack-cli ,在终端中运行npm install webpack webpack-cli(或者npm i webpack webpack-cli)

    首先我们在项目的根目录下,创建一个index.html,只在其中放一个id为app的容器

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
      <div id="app"></div>
    </body>
    </html>

    在根目录下创建一个src文件夹,里面创建一个main.js,通常情况下我们在vue项目里都是用.vue后缀的文件来写组件或者是页面(通常我们所谓的页面,实际只是借助路由跳转,不算真正意义的页面,通常我们会称之为页面),因为我们没有使用vue-cli搭建项目,所以并没有把vue的源码和webpack相结合,所以我们要手动引入vue的源码,使得我们可以使用vue的语法,那么我们应该先使用node安装一个vue的源码在终端中运行npm i vue,因为最新的我们是引入了vue3的源码,所以不再是将整个vue实例对象引入到项目中,因为在vue3中为了提高性能,所有的代码都是按需引入的,而不是像vue2一样将整个vue的实例对象引入到项目中,直接去使用实例对象上的方法。

    如果我们不在项目里引入vue的源码,那我们在main.js中只能写原生js的语法,如下:

    未引入vue源码的main.js:
    
    function comp() {
      const el = document.createElement("div");
    
      el.innerHTML = '<i>你好,vue-cli</i>'
    
      return el
    }
    
    document.body.appendChild(comp())

    2.png

    那如果我们再给他加点样式,应该怎么办呢?理论上而言webpack只能打包js文件,那css、less、以及vue后缀的文件它是怎么处理的呢?我们一步一步来看,既然是vue项目,我们通常都是写vue后缀的文件,有时候写项目为了方便同样也会在src文件下建一个style的文件夹,里面处理一些项目里的公共样式,但在此处,我们就不再嵌套文件夹,其实原理都是一样的,如果嵌套文件夹,只需要将文件的路径更改一下就能实现。

    main.js

    import { createApp } from 'vue';
    import './style.css'
    import App from './App.vue'
    
    const app = createApp(App)
    app.mount('#app')

    在src目录下,我们新建一个style.css文件和一个App.vue,其代码如下:

    style.css:

    div{
      color: red;
    }

    App.vue:

    <template>
      <div>
        每一份付出,都会使你得到什么
        <p @click="testFunctions">coding</p>
      </div>
    </template>
    
    <script>
    
    export default {
      setup() {
    
        function time() {
          const time = setTimeout(() => {
            console.log('hello webpack');
          },1000)
        }
    
        const testFunctions = async () => {
          await time()
          console.log('hello vue3');
        }
    
        return {
          testFunctions
        }
      }
    }
    </script>
    
    <style>
    div {
      color: aqua;
    }
    </style>

    项目其中基本的文件类型就是这些,如果你需要使用到.less的文件或者.stylus文件等,那么我们在webpack的四大核心之一的loader中去设置一些规则,使得将.less的文件或者.stylus文件先转化为.css文件,再告诉webpack去加载CSS文件

    既然要使用webpack的核心功能那么首先我们应该在根目录下创建一个webpack的配置文件webpack.config.js接下来我带着大家一起来一个一个核心部分来了解。

    入口(entry)

    入口起点(entry point) 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。 可以通过在 webpack 配置中配置 entry 属性,来指定一个入口起点(或多个入口起点)。默认值为 ./src

    module.exports = {
      entry: './src/main.js', // 项目入口文件(打包这个文件)
    };

    根据应用程序的特定需求,可以以多种方式配置 entry 属性。从入口起点章节可以了解更多信息。

    出口(output)

    output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output 字段,来配置这些处理过程:

    const path = require('path'); // node 提供的方法获取绝对路径
    
    module.exports = {
      entry: './src/main.js', // 项目入口文件(打包这个文件) 
      output: { 
          path: path.resolve(__dirname,'dist'), // webpack要求必须要绝对路径,__dirname项目文件的绝对路径 
          filename: 'js/[name].[contenthash].js' // 生成打包代码重命名 js[name].js 默认main.js 
         },
    };

    可能你想要了解在代码最上面导入的 path 模块是什么,它是一个 Node.js 核心模块,用于操作文件路径。

    Babel用法

    在实际开发中我们很少直接去接触babel,但是babel对于前端开发来说又是必不可少的。Babel到底是什么呢,它其实是一个工具链,跟postcss一样,它能够将ECMAScript后版本语法代码转为ES5代码,包括:语法转换、源代码转换、Polyfill实现功能。

    babel核心安装

    我们来安装babel核心库@babel/core,如果我们想要在命令行使用需要安装@babel/cli,安装npm install @babel/core @babel/cli。我们如果想使用babel的功能,就需要安装bable的插件,我们可以使用babel的预设插件@babel/preset-env,安装npm install @babel/preset-env -D

    babel.config.js:

    module.exports = {
      presets: [
        ["@babel/preset-env", {
          "targets": {
            "browsers": ["last 2 versions"]
          }
        }]
      ]
    }

    尽管现在市面上主流的浏览器已经适配了es6的语法,但是我觉得js语法降级也是我们需要掌握的;

    loader

    loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。

    本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

    注意,loader 能够 import 导入任何类型的模块(例如 .css 文件),这是 webpack 特有的功能,其他打包程序或任务执行器的可能并不支持。我们认为这种语言扩展是有很必要的,因为这可以使开发人员创建出更准确的依赖关系图。

    在更高层面,在 webpack 的配置中 loader 有两个目标:

    const path = require('path');  // node 提供的方法获取绝对路径
    module.exports = {
      mode: 'development', // 开发模式(打包出来的代码不会被压缩)转化为html、css、js,图片压缩等
      entry: './src/main.js', // 项目入口文件(打包这个文件)
      output: {
        path: path.resolve(__dirname,'dist'),  // webpack要求必须要绝对路径,__dirname项目文件的绝对路径
        filename: 'js/[name].[contenthash].js' // 生成打包代码重命名 js[name].js  默认main.js
      },
      module: {
        rules: [
          {
            test: /\.css$/i,  //正则表达式
            use: ['style-loader', 'css-loader']  // 从右向左执行,有先后顺序 
          },
          {
            test: /\.vue$/i,  //正则表达式
            use: ['vue-loader']  // 从右向左执行,有先后顺序 
          },
          {
            test: /\.js$/i,  //正则表达式
            exclude: '/node_modules',
            use: ['babel-loader']
          }
        ]
      }
    }

    在一般的vue项目中我们需要使用node安装三个loader npm i style-loadernpm i css-loadernpm i vue-loader,同时还需要一个vue的编译插件npm i @vue/compiler-sfc,其作用是将vue的语法编译成抽象语法树(虚拟dom结构),

    3.png

    换句话说就是将.vue文件的三个部分取出来,分别放到`script` 、 `template` 、 `style` 三个部分中去。

    插件(plugins)

    loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

    想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

    首先为了打包之后生成一个新的html的文件,我们需要安装一个插件npm i html-webpack-plugin -D该插件将为你生成一个 HTML5 文件,配置文件如下:

    const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
    const path = require('path');  // node 提供的方法获取绝对路径
    const { VueLoaderPlugin } = require('vue-loader/dist/index')
    const { CleanWebpackPlugin } = require('clean-webpack-plugin')  
    module.exports = {
      mode: 'development', // 开发模式(打包出来的代码不会被压缩)转化为html、css、js,图片压缩等
      entry: './src/main.js', // 项目入口文件(打包这个文件)
      output: {
        path: path.resolve(__dirname,'dist'),  // webpack要求必须要绝对路径,__dirname项目文件的绝对路径
        filename: 'js/[name].[contenthash].js' // 生成打包代码重命名 js[name].js  默认main.js
      },
      module: {
        rules: [
          {
            test: /\.css$/i,
            use: ['style-loader', 'css-loader']  // 从右向左执行,有先后顺序 
          },
          {
            test: /\.vue$/i,
            use: ['vue-loader']  // 从右向左执行,有先后顺序 
          },
          {
            test: /\.js$/i,
            exclude: '/node_modules',
            use: ['babel-loader']  // 我们安装的一个插件,使得es6之后的语法转化为es5
          }
        ]
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: path.resolve(__dirname,'./index.html'),  // 需要打包的html文件的绝对路径
          filename: 'index.html',   // 打包之后的文件可以重命名
          title: '手动搭建vue-cli'   //还可以修改打包后的HTML中的title
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin() // 清除上一次打包的内容删除,使得下一次的打包顺利进行
      ]
    }

    在插件中修改HTML的title,需要在HTML中写一行代码<title><%= htmlWebPlugin.options.title%></title>, htmlWebPlugin就是我们在plugin里new出来的实例对象,同时我们之前安装的vue-loader的功能不仅仅是帮我们去读懂.vue后缀的文件,我们也可以当一个插件来使用;首先引入const { VueLoaderPlugin } = require('vue-loader/dist/index'),在plugin里面new一下我们引用的这个构造函数,它的作用是将我们定义过的规则复制并应用到.vue文件相应的语法块中。

    模式

    通过选择 development开发模式 或 production 生产模式之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化

    module.exports = {
      mode: 'production'
    };

    到现在我们基本的vue-cli的功能已经实现了,但是我们会发现,我们使用vue-cli运行项目的时候我们是直接跑了一个本地端口的服务,所以我们只需要在最后配置一下DevServer

    devServer: {
        static: {
          directory: path.join(__dirname, 'dist'),  // 跑起来的服务的文件
        },
        compress: true,  // 是否压缩
        port: 8080,   // 本地开启服务的端口号
        open: true  // 运行服务之后是否自动打开
      }

    package.json

    {
      "name": "vue-cli",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack",    //我们使用 npm run build 将项目打包至dist文件夹
        "dev": "webpack serve" // 我们使用 npm run dev 将项目运行起来
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@babel/core": "^7.19.1",
        "@babel/preset-env": "^7.19.1",
        "babel-loader": "^8.2.5",
        "clean-webpack-plugin": "^4.0.0",
        "css-loader": "^6.7.1",
        "html-webpack-plugin": "^5.5.0",
        "style-loader": "^3.3.1",
        "vue": "^3.2.39",
        "webpack": "^5.74.0",
        "webpack-cli": "^4.10.0",
        "webpack-dev-server": "^4.11.1"
      },
      "dependencies": {
        "@vue/compiler-sfc": "^3.2.39",
        "vue-loader": "^17.0.0"
      }
    }

    完整的webpack.config.js配置文件:

    const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
    const path = require('path');  // node 提供的方法获取绝对路径
    const { VueLoaderPlugin } = require('vue-loader/dist/index')
    const { CleanWebpackPlugin } = require('clean-webpack-plugin')
    module.exports = {
      mode: 'development', // 开发模式(打包出来的代码不会被压缩)转化为html、css、js,图片压缩等
      entry: './src/main.js', // 项目入口文件(打包这个文件)
      output: {
        path: path.resolve(__dirname,'dist'),  // webpack要求必须要绝对路径,__dirname项目文件的绝对路径
        filename: 'js/[name].[contenthash].js' // 生成打包代码重命名 js[name].js  默认main.js
      },
      module: {
        rules: [
          {
            test: /\.css$/i,
            use: ['style-loader', 'css-loader']  // 从右向左执行,有先后顺序 
          },
          {
            test: /\.vue$/i,
            use: ['vue-loader']  // 从右向左执行,有先后顺序 
          },
          {
            test: /\.js$/i,
            exclude: '/node_modules',
            use: ['babel-loader']
          }
        ]
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: path.resolve(__dirname,'./index.html'),
          filename: 'index.html',
          title: '手动搭建vue-cli'
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin()
      ],
      devServer: {
        static: {
          directory: path.join(__dirname, 'dist'),
        },
        compress: true,
        port: 8080,
        open: true
      }
    }

    实际效果展示:

    4.gif

    (学习视频分享:web前端开发编程基础视频

    以上就是手把手教你使用webpack实现vue-cli的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    快捷开发Web应用及小程序:点击使用

    支持亿级表,高并发,自动生成可视化后台。

    专题推荐:Vue Vue CLI vue3 webpack
    上一篇:Vite项目怎么进行屏幕适配?两种方案分享 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 实例详解,带你玩转 Vue 动画• 聊聊怎么Vue中避免在动态绑定类时出现空类的情况!• 手把手带你在 Vue2 中自定义一个图片懒加载指令• vue不能用index做为唯一标识的原因浅析• 原理详解:Vue3中reactive和ref的区别
    1/1

    PHP中文网