乐趣区

Webpack4-从零搭建-Vue-项目

作者:NCUHOME-FED Flura 的博客
已经获得原作者授权

主要设置

创建项目

新建一个项目文件夹

npm init -y 初始化 package.json

安装 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"
  }
}
退出移动版