vue2--webpack&&单文件组件

webpack

  • 文件依赖关系复杂
  • 静态资源请求效率低
  • 模块化支持并不友好
  • 浏览器对高级js特性兼容程度低

在项目中安装webpack

  • 项目初始化:npm init -y
  • 运行npm i webpack webpack-cli -D命令,安装webpack相关的包
  • 在项目根目录创建名为webpack.config.js的webpack配置文件
  • 在webpack配置文件中初始化如下基本配置:
    1
    2
    3
    4
    module.exports = {
    mode: 'development'//mode用于指定构建模式,该值表示转换出来的代码不会进行压缩和转换,转换时间短一些,如果是production就会对转换出来的代码进行压缩和转换,相对应转换时间长一些
    //开发阶段一般是指定为development,上线了就转换为production
    }
  • 在package.json文件中配置文件中的scripts节点下,新增dev脚本:
    1
    2
    3
    "scripts": {
    "dev": "webpack" //在script节点下的脚本,可以通过npm run 执行
    }
  • 在终端中运行npm run dev命令,可以启动webpack进行项目打包

配置文件的入口与出口

  • 在webpack的4.x版本中默认约定:打包的入口文件为src -> index.js
  • 打包的输出文件为dist -> main.js
  • 如果需要修改打包的入口与出口,可以在webpack.config.js中新增如下配置信息:
    1
    2
    3
    4
    5
    6
    7
    8
    const path = require('path') //导入node.js中专门操作路径的模块
    module.exports = {
    entry: path.join(__dirname,'./src/index.js'),//打包入口文件的路径
    output: {
    path: path.join(__dirname,'./dist'),//输出文件的存放路径
    filename: 'bundle.js'//输出文件的名称
    }
    }

配置自动打包功能

  • 运行npm i webpack-dev-server -D命令,安装支持项目自动打包的工具
  • 修改package.json -> scripts中的dev命令如下:
    1
    2
    3
    "scripts": {
    "dev": "webpack-dev-server" //scripts下的脚本,可以通过npm run执行
    }
  • 将src -> index.html中scripts脚本的引用路径修改为”/bundle.js”(打包后的根路径下的js文件的位置)
  • 运行 npm run dev命令,重新进行打包
  • 在浏览器中访问http://localhost:8080地址,查看自动打包效果(是该文件的根目录中的页面)
  • 该方法运行生成的根目录下虚拟的一个存在与虚拟磁盘上的bundle.js文件(不存在物理磁盘上)
  • 所以上述步骤中脚本引用路径修改一定要是在根路径下的任意js文件

注意:

  • webpack-dev-server会启动一个实时打包的http服务器
  • webpack-dev-server打包生成的输出文件,默认放到了项目根目录,而且是虚拟的、看不见的,没有存在物理磁盘上,但是在运行以后的项目中可以访问到
  • 该方法只是将文件的路径放到了网页上,但是并没有将页面放到页面上

直接运行完以后弹出浏览器运行页面:
需要配置自动打包的相关参数:

1
2
3
4
5
6
7
//package.json中的配置
//--open打包完成后项目自动打开浏览器页面
//--host配置ip地址
//--port配置端口
"scripts": {
"dev": "webpack-dev-server --open --host 127.0.0.1 --port 8080" //scripts下的脚本,可以通过npm run执行
}

配置html-webpack-plugin生成预览页面

主要思想:只要把src中的index.html文件放到根目录下面就可以了,只要一进入该文件路径,发现index.html就会直接打开该文件

  • 运行npm i html-webpack-plugin -D命令,安装生成预览页面的插件
  • 修改webpack.config.js文件头部区域,添加如下配置信息:
    1
    2
    3
    4
    5
    6
    7
    //导入生成预览页面的插件,得到一个构造函数
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const htmlPlugin = new HtmlWebpackPlugin({
    //创建插件的实例对象
    template: './src/index.html',//指定要用到的模板文件
    filename: 'index.html' //指定生成的文件名称,该文件存在于内存中,在目录中不显示
    })
  • 修改webpack.config.js文件向外暴露的配置对象,新增如下配置节点:
    1
    2
    3
    module.exports = {
    plugins: [ htmlPlugin ]//plugins数组是webpack打包期间会用到的一些插件列表
    }

webpack加载器

在实际开发过程中,webpack默认只能打包处理以.js后缀名结尾的模块,其他非.js后缀名结尾的模块,webpack默认处理不了,需要调用loader加载器才可以正常打包,否则报错!!

loader、加载器会协助webpack打包处理待定的文件模块,比如:

  • less-loader可以打包处理.less相关的文件
  • sass-loader可以打包处理.sass相关的文件
  • url-loader可以打包处理css中与url路径相关的文件

基本使用

打包处理css文件:
  • 运行npmnpm i style-loader css-loader -D命令,安装处理css文件中的loader
  • 在webpack.config.js的module -> rules数组中,添加loader规则如下:
    1
    2
    3
    4
    5
    6
    7
    8
    //所有第三方模块的匹配规则
    //test表示匹配的文件类型,正则表达式;use表示对应要调用的loader
    module:
    {
    rules: [
    { test: /\.css$/, use: ['style-loader','css-loader'] }
    ]
    }
  • 注意事项:
    • use数组中指定的loader顺序是固定的
    • 多个loader的调用顺序是:从后往前调用
打包处理less文件
  • 运行npm i less-loader less -D命令
  • 在webpack.config.js的module -> rules数组中,添加loader规则如下:
    1
    2
    3
    4
    5
    module: {
    rules: [
    { test: /\.less$/, use: ['style-loader','css-loader'],['less-loader'] }
    ]
    }
配置postCSS自动添加css的兼容前缀
  • 运行npm i postcss-loader autoprefixer -D命令
  • 在项目根目录中创建postcss的配置文件postcss.config.js。并初始化如下配置:
    1
    2
    3
    4
    const autoprefixer = require('autoprefixer')//导入自动添加前缀的插件
    module.exports = {
    plugins: [ autoprefixer ]//挂载插件
    }
  • 在webpack.config.js的module -> rules数组中,添加loader规则如下:
    1
    2
    3
    4
    5
    6
    module: 
    {
    rules: [
    { test: /\.css$/, use: ['style-loader','css-loader','postcss-loader'] }
    ]
    }
打包样式表中的图片和字体文件
  • 运行npm i url-loader file-loader -D命令
  • 在webpack.config.js的module -> rules数组中,添加loader规则如下:
    1
    2
    3
    4
    5
    6
    7
    module: 
    {
    rules: [
    { test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
    use: ['url-loader?limit=16940'] }
    ]
    }
    其中?之后的是loader的参数项。limit用来指定图片的大小,单位是字节(byte),只有小于limit大小的图片,才会被转为base64图片。
打包处理js中的高级语法
  • 安装babel转换器相关的包:npm i babel-loader @babel/core @babel/runtime -D
  • 安装babel语法插件相关的包:npm i @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
  • 在项目根目录创建Babel配置文件babel.config.js并初始化如下:
    1
    2
    3
    4
    module.exports = {
    presets: ['@babel/preset-env'],
    plugins: [ '@babel/plugin-transform-runtime', '@babel/plugin-proposal-class-properties']
    }
  • 在webpack.config.js的module->rules数组中,添加loader规则如下:
    1
    2
    3
    //exclude为排除项,表示babel-loader不需要处理node_modules中的js文件
    //因为node_modules中的js都是第三方包提供的,我们只需要转换用户自己写的js文件
    { test: /\.js$/,use: 'babel-loader', exclude: /node_modules/ }

单文件组件

传统组件的问题:

  • 全局定义的组件必须保证组件的名称不重复
  • 字符串模板缺乏语法高亮,在HTML有多行的时候,需要用到丑陋的\
  • 不支持css意味着当HTML和js组件化时,css被明显遗漏
  • 没有构建步骤限制,只能使用HTML和ES5js,而不能使用预处理器

正对针对上述问题提出了Vue单文件组件。每个单文件组件的后缀名都是.vue
组成结构:

  • template:组件的模板区域
  • script:业务逻辑区域
  • style:样式区域

webpack配置vue组件的加载器

  • 运行npm i vue-loader vue-template-compiler -D
  • 在webpack.config.js配置文件中,添加vue-loader的配置项
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    module.exports = {
    module:{
    rules: [
    { test: /\.vue$/, use: 'vue-loader'}
    ]
    },
    plugins: [
    new VueLoaderPlugin()//确保导入这个插件
    ]
    }

在webpack项目中使用vue

  • 运行npm i vue -S安装vue
  • 在src -> index.js入口文件,通过import Vue from ‘vue’来导入vue构造函数
  • 导入根组件
  • 创建vue的实例对象,并指定要控制的el区域
  • 通过render函数渲染App根组件

webpack的打包发布

上线之前通过webpack将应用进行整体打包,可以通过package.json文件配置打包命令:

1
2
3
4
5
6
7
8
//在package.json文件中配置webpack打包命令
//该命令默认加载项目根目录中的webpack.config.js配置文件
"scripts": {
//用于打包的命令
"build": "webpack -p",
//用于开发调试的命令
"dev": "webpack-dev-server --open --host --127.0.0.1 --port 3000"
}

打包后的文件会自动加入dist目录中,所以打包之前可以先将dist目录删除。

-------------本文结束感谢您的阅读-------------