Webpack入门之使用Webpack打包Vue文件

2,193 阅读3分钟

使用Webpack编译ES6+代码

创建webpack-demo-vue文件夹并使用vscode打开

呼出终端

1.输入yarn init -y

可以自动生成一个package.json配置文件

image-20210128103540152

2.安装webpack 和webpack命令行工具yarn add webpack webpack-cli -D

注意-D,webpack和webpack-cli不参与生产环境的任务,所以安装到开发环境

可以看到多了一个node_modules文件夹,这是用来放置各类安装包的;yarn-lock文件不需要去管,这是用来锁定依赖版本的

在package.json多了devDependencies配置项,里面有我们刚才安装的两个工具

image-20210128104420387

3. 继续安装 yarn add babel-loader @babel/core @babel/preset-env -D

babel-loader 在webpack中使用babel编译ES,需要babel-loader

@babel/core es代码编译的核心

@babel/preset-env 转换规则,高版本es转低版本,把ES6+代码转为ES5

4.创建src文件夹​→​创建index.js

在index.js中编写一段ES6代码

[1,2,3].map(item=>console.log(item))

如果不是全局安装的webpack-cli,就需要在package.json中添加指令"build": "webpack --config ./webpack.config.js"

然后用yarn build命令执行编译代码,或者找到node_modules/.bin/webpack命令工具,命令行输入./node_modules/.bin/webpack来编译,新版本的webpack会自动搜寻src目录中的文件编译,在根目录自动生成dist文件夹和编译后的文件

打开dist/main.js,可以发现这不是我们要的结果,箭头函数还是箭头函数

image-20210128113756509

5.接下来我们需要在根目录创建webpack.config.js进行配置

const path=require('path')//处理路径的模块

module.exports={//输出配置
  mode:"production",//默认是生产模式
  entry:"./src/index.js",//入口文件
  output:{
    path:path.join(__dirname,"dist"),//输出执行文件(指webpack.config.js)的绝对路径
    filename:"boundle.js"//指定输出文件名,替换main.js
  },
  module:{
    rules:[
      {
        test:/\.js$/,//匹配js文件
        exclude:/node_modules/,//忽略node_modules文件夹
        use:{
          loader:'babel-loader',
          options:{
            presets:['@babel/preset-env']
          }
        }
      }
    ]
  }
}

此时执行yarn build,输出了我们想要的结果

image-20210128121253812

6.使用html-webpack-plugin创建html页面

安装yarn add html-webpack-plugin -D,这个插件会自动引入js文件

webpack.config.js配置

const path=require('path')
const HtmlWebpackPlugin=require('html-webpack-plugin') 

module.exports={
  ...
  plugins:[
    new HtmlWebpackPlugin({//创建实例
      filename:'index.html',// 指定文件名
      template:path.resolve(__dirname,'src/index.html')//引入路径
    })
  ]
}

虽然在webpack.config.js中配置了index.html的引入路径,但我们还没有创建→在src文件夹下创建index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="root">
    <span>蒜头王八</span>
  </div>
</body>
</html>

yarn build 编译,下图中可以看到src中的index.html文件在dist文件夹中编译成功了,并自动引入了js文件

image-20210128125515233

进入正题编译Vue文件

1.安装Vue的相关工具

yarn add vue 安装Vue

yarn add vue-loader -D 安装vue-loader解析.vue文件

yarn add vue-template-compilervue-template-compiler编译vue模板

2.在src文件夹下创建相关文件

创建App.vue

<template>
    <div class="app">
      <h1>App文件</h1>
      <span>{{msg}}</span>
    </div>
</template>

<script>
export default {
  name: '',
  data () {
    return {
      msg:"蒜头王八"
    }
  }
}
</script>

index.html中内容删掉,只留一个div用来挂载App.vue

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="root">
  </div>
</body>
</html>

再来编写下核心的入口文件index.js,把之前的测试代码删掉

import Vue from 'vue'
import App from './App.vue'

new Vue({
  el:"#root", //挂载的html节点
  render:h=>h(App) //渲染 相当于 render:function(createElement){return createElement(App)}
})

配置webpack.config.js,注意vue-plugin的引入,module中rules的新增,plugins的新增

const path=require('path')
const HtmlWebpackPlugin=require('html-webpack-plugin') 
const VueLoaderPlugin=require('vue-loader/lib/plugin')

module.exports={
  mode:"production",//默认是生产模式
  entry:"./src/index.js",//入口文件
  output:{
    path:path.join(__dirname,"dist"),//输出执行文件(指webpack.config.js)的绝对路径
    filename:"boundle.js"//指定输出文件名,替换main.js
  },
  module:{
    rules:[
      {
        test:/\.js$/,//匹配js文件
        exclude:/node_modules/,//忽略node_modules文件夹
        use:{
          loader:'babel-loader',
          options:{
            presets:['@babel/preset-env']
          }
        }
      },
      {
        test:/\.vue$/,
        use:{
          loader:'vue-loader'
        }
      }
    ]
  },
  plugins:[
    new HtmlWebpackPlugin({//创建实例
      filename:'index.html',// 指定文件名
      template:path.resolve(__dirname,'src/index.html')//引入路径
    }),
    new VueLoaderPlugin()
  ]
}

命令行yarn build,编译完成后在浏览器打开dist文件夹中的index.html,如下图,可以看到成功编译vue文件

image-20210128174831966

3.配置本地服务

yarn add webpack-dev-server -D,并在package.json的scripts中新增一行"start": "webpack-dev-server --open"--open参数可以让项目直接在默认浏览器打开

好了,命令行输入yarn start,结果报错,如下图

image-20210128181816244

工具类问题,一般的搜索找不到解决办法,最好是去github上去找,大多有解决方案

image-20210128182039495

原因就是版本之间不兼容,直接安装的版本如图

image-20210128182300017

退回3.3.12版本就行,卸载webpack-cli​→​yarn remove webpack-cli,再安装指定版本yarn add webpack-cli@3.3.12 -D,然后命令行输入yarn start,如下图,成功了!

image-20210128182606039

4.解析CSS

之前的项目中都没有写入CSS代码,webpack编译CSS代码需要css-loader和style-loader。

安装这两个loader,yarn add css-loader style-loader -D

loader的配置顺序和加载顺序是相反的,如果配置是下面顺序,则会报错

{
  test:/\.css$/,
  use:[
    'css-loader'
    'style-loader',
  ]
}

需要先加载css-loader,再加载style-loader把css塞进页面中去,webpack.config.js配置如下

...
  module:{
   ...
      {
        test:/\.vue$/,
        use:{
          loader:'vue-loader'
        }
      },
      {
        test:/\.css$/,
        use:[
          'style-loader',//两个loader顺序做了替换
          'css-loader'
        ]
      }
    ]
  },
  ...
}

同时App.vue中添加CSS代码

<template>
    <div class="app">
      <h1>App文件</h1>
      <span>{{msg}}</span>
    </div>
</template>

<script>
export default {
  name: '',
  data () {
    return {
      msg:"蒜头王八"
    }
  }
}
</script>

<style>
  .app{
    color: red;
  }
</style>

yarn start后,成功

image-20210128184946436

5.如果平时习惯用sass呢?

安装node-sass以及sass-loaderyarn add node-sass sass-loader -D

如果安装node-sass失败,可以用dart-sass替换→yarn add node-sass@npm:dart-sass

配置webpack.config.js,更新rules

...
  module:{
    rules:[
      ...
      {
        test:/\.(sa|c)ss$/, //同时匹配sass和css
        use:[
          'style-loader',
          'css-loader',
          'sass-loader'//新增sass-loader
        ]
      }
    ]
  },
...

App.vue中更新style部分,使用sass语法

<style lang="sass">
  .app{
    color: red;
    span{
      color: green;
    }
  }
</style>

yarn start 后,浏览器中span的字体绿了

image-20210128185918210

到此这篇文章的主题内容就结束了。

6.一些问题

  • 做项目的过程中发现一些问题。🌰如:App.vue文件如果不写后缀就会报错,懒癌发作不想写咋办

image-20210128205145984

解决这个问题,只要在webpack.config.js中配置就行

...
module.exports={
  mode:"production",//默认是生产模式
  resolve:{
    extensions:['.vue','.js'] //允许用户在引入模块时不带扩展名即文件后缀。根据文档,如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
  },
  entry:"./src/index.js",//入口文件
  ...
 }
  • 另一个问题:我们对html中数据更改的时候,不是热更新,而是一段时间后的浏览器自刷新,这个怎么解决?

webpack.config.js中配置如下

...
const webpack=require('webpack')//1

module.exports={
 ...
  plugins:[
    new HtmlWebpackPlugin({
      filename:'index.html',
      template:path.resolve(__dirname,'src/index.html')
    }),
    new VueLoaderPlugin(),
    new webpack.HotModuleReplacementPlugin()  //2引入热更新模块
  ],
  devServer:{//3
    hot:true
  }
}

在入口页面添加代码

import Vue from 'vue'
import App from './App'

if(module.hot){
  module.hot.accept(error=>{//accept是接受热更新,decline自然是拒绝
    if(error)console.log('热替换出错');
  })
}

new Vue({
  el:"#root", 
  render:h=>h(App) 
})

此时运行项目,再修改页面内容,会发现5秒后在页面没刷新的情况下对内容进行了变更。

这个高延迟显然不是我们需要的,这是webpack.config.js中的mode:'production'造成的,变更为development模式,你会发现,嗯!真香!

DEMO的github链接