webpack4从零搭建vue项目

主要设置

创建项目

新建一个项目文件夹

npm init -y 初始化package.json

image

安装webpack依赖包

npm install --save-dev webpack webpack-cli webpack-dev-server

  devServer: {
    contentBase: path.join(__dirname, './dist'),
    host: 'localhost',  //  可以设置0.0.0.0 ,这样设置你可以通过127.0.0.1或则localhost去访问
    open: true,       //  项目启动时,会默认帮你打开浏览器
    port: 8088,
    // hot: true    //在单页面应用开发中,我们修改了代码后是整个页面都刷新,开启hot后,将只刷新对应的组件
  }

安装vue

npm install vue

npm install -D vue-loader vue-template-compiler

vue-loader webpack配置 参考官方文档-手动设置

 // webpack.base.config.js
      const VueLoaderPlugin = require('vue-loader/lib/plugin')
  module.exports = {
  module: {
      rules: [
      // ... 其它规则
      {
          test: /\.vue$/,
          loader: 'vue-loader'
      }
      ]
  },
  plugins: [
      // 请确保引入这个插件!
      new VueLoaderPlugin()
  ]
 }

config详细配置

新建一个src文件夹,并在src文件下新建index.js,在根目录下新建webpack.config.js

webpack.config.js的配置

  • ​ webpack.config.js 配置,webpack-dev-server工具的使用。

html-webpack-plugin 可以指定template模板文件,将会在output目录下,生成html文件,并引入打包后的js.

安装依赖:

npm install --save-dev html-webpack-plugin

配置webpack.config.js module中的rules

const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    //...other code
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'src/index.html')
        })
    ]

}

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

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, '/dist'),//打包生成文件地址    
    filename: 'bundle.js',
    // publicPath: '/dist/'//文件输出的公共路径
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        use: [
          "vue-loader"
        ]
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          "style-loader",
          "css-loader"
        ]
      },
      {
        test: /\.js?$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/react'],
              plugins: [
                [require("@babel/plugin-proposal-decorators"), { "legacy": true }]
              ]
            }
          }
        ],
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new htmlWebpackPlugin({
      template: './index.html'
    }),
    new VueLoaderPlugin()  // vueLoader插件 允许你以一种名为单文件组件的格式撰写 Vue 组件
  ],
  devServer: {
    contentBase: path.join(__dirname, './dist'),
    host: 'localhost',  //  可以设置0.0.0.0 ,这样设置你可以通过127.0.0.1或则localhost去访问
    open: true,       //  项目启动时,会默认帮你打开浏览器
    port: 8088,
    // hot: true    //在单页面应用开发中,我们修改了代码后是整个页面都刷新,开启hot后,将只刷新对应的组件
  }
}

创建项目目录文件

在根目录下创建一个index.html文件作为启动页面,一个webpack.config.js作为webpack配置文件(实际项目中这里会有webpack配置文件,分别用于开发环境和生产环境,这里简便起见就用一个配置文件) ,再创建一个App.vue文件。

cet-query
├─ index.html 启动页面
├─ package-lock.json
├─ package.json 包管理
├─ src
│    └─ index.js 入口文件
|    └─ App.vue 
└─ webpack.config.js  webpack配置文件

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>cet-query title</title>
</head>
<body>
  
</body>
</html>

index.js

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

const root = document.createElement('div') //创建div节点
document.body.appendChild(root) //将div节点添加到body下

new Vue({
  render: (h) => h(App)  //vue在创建Vue实例时,通过调用render方法来渲染实例的DOM树,也就是这个组件渲染的是App的内容
                        //vue在调用render方法时,会传入一个createElement函数作为参数,也就是这里的h的实参是createElement函数,然后createElement会以App为参数进行调用
}).$mount(root)

App.vue

<template>
  <div id="app">
    I am App.vue
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>

</style>

添加启动脚本

在package.json添加启动脚本命令

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development --progress --hide-modules",
    "dev": "webpack-dev-server --mode=development"
  },

这样执行npm run dev就能启动成功了, npm run build也能打包生成dist文件

其它扩展处理

引入babel-loader兼容代码

babel-preset-env 帮助我们配置 babel。我们只需要告诉它我们要兼容的情况(目标运行环境),它就会自动把代码转换为兼容对应环境的代码。ES6/ES7/JSX 转义需要 Babel 的依赖,支持装饰器。

npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread

更改webpack.config.js文件

{
  test: /\.js?$/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        presets: ['@babel/preset-env', '@babel/react'],
        plugins: [
          [require("@babel/plugin-proposal-decorators"), { "legacy": true }]
        ]
      }
    }
  ],
  include: path.resolve(__dirname, 'src'),
  exclude: /node_modules/
},

配置css

输入命令下载style-loader css-loader

npm i style-loader css-loader -D

配置webpack.config.js module中的rules

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

如果要打包scss或者其它,再安装对应的loader。

支持sass

输入命令下载sass-loader node-sass

npm i sass-loader node-sass -D
复制代码

修改webpack.config.js的css

{   
  test: /\.sass$/,   
  use:['vue-style-loader', 
     'css-loader', 'sass-loader' 
  ],   
  include: path.resolve(__dirname + '/src/'),    
  exclude: /node_modules/ 
},

支持图片

输入命令下载file-loader url-loader

npm i file-loader url-loader -D

配置webpack.config.js module中的rules

{   
  test: /\.(jpg|png|gif|svg)$/,   
  use: 'url-loader',   
  include: path.resolve(__dirname + '/src/'),   
  exclude: /node_modules/ 
}

完整的文件参考

webpack.config.js文件

const path = require('path')  //path是Nodejs中的基本包,用来处理路径
const htmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, '/dist'),  //打包生成文件地址    
    filename: 'bundle.js',
    // publicPath: '/dist/'  //文件输出的公共路径
  },
  module: {  
    rules: [     //针对不同类型的文件,我们定义不同的识别规则,最终目的都是打包成js文件
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        use: [
          "vue-loader"     //处理.vue文件
        ]
      },
      {
        test: /\.css$/,     //处理css
        exclude: /node_modules/,
        use: [
          "style-loader",
          "css-loader"
        ]
      },
      {
        test: /\.js?$/,    //处理js
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/react'],
              plugins: [
                [require("@babel/plugin-proposal-decorators"), { "legacy": true }]
              ]
            }
          }
        ],
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/
      },
      {
        test: /\.(png|gif|jpg|jpeg|svg)$/,     //处理图片
        exclude: /node_modules/,
        use: [
          "url-loader"
        ]
      }
    ]
  },
  plugins: [
    new htmlWebpackPlugin({
      template: './index.html'
    }),
    new VueLoaderPlugin()  // vueLoader插件 允许你以一种名为单文件组件的格式撰写 Vue 组件
  ],
  devServer: {
    contentBase: path.join(__dirname, './dist'),
    host: 'localhost',  //  可以设置0.0.0.0 ,这样设置你可以通过127.0.0.1或则localhost去访问
    open: true,       //  项目启动时,会默认帮你打开浏览器
    port: 8088,
    // hot: true         //在单页面应用开发中,我们修改了代码后是整个页面都刷新,开启hot后,将只刷新对应的组件
  }
}

package.json文件

{
  "name": "cet-query",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development --progress --hide-modules",
    "dev": "webpack-dev-server --mode=development"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/fuchengjx/cet-query.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/fuchengjx/cet-query/issues"
  },
  "homepage": "https://github.com/fuchengjx/cet-query#readme",
  "dependencies": {
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@babel/plugin-proposal-decorators": "^7.4.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
    "@babel/preset-env": "^7.5.5",
    "@babel/preset-react": "^7.0.0",
    "babel-core": "^6.26.3",
    "babel-loader": "^8.0.6",
    "babel-preset-env": "^1.7.0",
    "css-loader": "^3.1.0",
    "html-webpack-plugin": "^3.2.0",
    "style-loader": "^0.23.1",
    "vue-loader": "^15.7.1",
    "vue-template-compiler": "^2.6.10",
    "webpack": "^4.39.1",
    "webpack-cli": "^3.3.6",
    "webpack-dev-server": "^3.7.2"
  }
}

[博客参考链接](https://flura.cn/2019/08/05/webpack4%E4%BB%8E%E9%9B%B6%E6%90%AD%E5%BB%BAvue%E9%A1%B9%E7%9B%AE/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容