webpack配置

1、全局安装

npm i -g webpack


2、新建空文件夹 初始化生成package.json

npm init -y


3、安装webpack-cli

npm install webpack webpack-cli --save-dev


4、创建目录和文件

初始化生成的 package.json

{
  "name": "webpackpro",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  }
}

5、修改package.json文件

//便确保我们安装包是私有的(private),并且移除 main 入口。这可以防止意外发布你的代码。
{
  "name": "webpackpro",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "build": "webpack --mode production",
    "dev": "webpack --mode development"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  }
}

6、配置webpack.config.js

6.1 配置出入口文件:

const path = require('path')
module.exports={
    entry:"./src/main.js", //入口文件
    output:{  //出口文件
        filename:"[name].js", 
        path:path.resolve(__dirname,"dist")  // __dirname绝对路径
    }
}

此时运行 npm run build 便会在dist中生成打包后的文件main.js

6.2 配置plugins 自动生成html文件

  const path = require('path')
  const HtmlWebpackPlugin = require('html-webpack-plugin');
  const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  module.exports={
      mode:'development',
      entry:"./src/main.js",
      output:{
          filename:"[name].js",
          path:path.resolve(__dirname,"dist")
      },
      plugins: [
          // new VueLoaderPlugin(),
          new CleanWebpackPlugin(), //每次在打包时,文件都是已覆盖已有的,不删除多余的。执行npm run build后dist目录先被删除然后在重新根据配置生成。
          new HtmlWebpackPlugin({      //自动生成一个引入了打包后JS的html
              template: path.resolve(__dirname, './public/index.html'),//模板文件
              filename: 'index.html'//生成的文件名称
          }),
      ],    
  }

运行 npm run build 生成index.html和main.js

6.3配置devServer

安装webpack服务 自动监测代码变化并实时刷新浏览器

  • npm install --save-dev clean-webpack-plugin
    devServer:{
        contentBase:'./dist',    //服务器启动的目录
        open:true,   //自动打开浏览器
        proxy:{    //设置代理,可用于本地mock数据,本地自己启动另外一个服务
            "/api":{
                target:"http://localhost:9092"
            }
        },
        port:8083, //指定端口号
        hot:true,   //开启HMR(Hot Module Replacement)热模块替换,由于是webpack自带的,所以要引入webpack ,监控并更新js模块的工作vue等框架自己做了,否则需要自己手动监控 
        hotOnly:true
    },

修改package.json

  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "build": "webpack --mode production",
    "dev": "webpack-dev-server --open --hot --mode development"
  },

devServer中hot有时不起作用,建议写到package.json中。
open hot inline 只能在devserve或者package.json中写一个
具体原因:https://segmentfault.com/a/1190000007429897
此时运行 npm run dev 会在本地启动一个nodejs的web服务,并自动打开localhost:9000

6.4 使用source-map追踪源代码错误

    devServer:{
        contentBase:'./dist',    //服务器启动的目录
        open:true,   //自动打开浏览器
        proxy:{    //设置代理,可用于本地mock数据,本地自己启动另外一个服务
            // "/api":{
            //     target:"http://localhost:9000"
            // }
        },
        // 方便追踪源代码错误
        devtool: 'source-map',
        // port:9000, //指定端口号 默认8080
        // hot:true,   //开启HMR(Hot Module Replacement)热模块替换,由于是webpack自带的,所以要引入webpack ,监控并更新js模块的工作vue等框架自己做了,否则需要自己手动监控 
        // hotOnly:true
    },

在编译生成的dist目录中,js代码已被重新混淆,如果出现错误,无法将错误正确定位到原始代码的对应位置,这样不方便调试生成环境的代码。如果需要精确调试生产环境代码,可通过source-map实现。(如果不需要此功能,可以跳过本节)

6.5 拆分webpack.config.js 区别开发环境和生产环境

  • 安装插件拆分 npm install webpack-merge --save-dev
  • 新建三个文件:
    webpack.base.js (公共配置)
    webpack.dev.js (开发环境配置)
    webpack.prod.js (生产环境配置)
    将webpack.config.js代码拆分后,可删除webpack.config.js。
  • 区分生产环境和开发环境 :https://my.oschina.net/46395665/blog/3111922/print

webpack.base.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports={
    mode:'development',
    entry:"./src/main.js",
    output:{
        filename:"[name].js",
        path:path.resolve(__dirname,"dist")
    },
    plugins: [
        // new VueLoaderPlugin(),
        new CleanWebpackPlugin(), //每次在打包时,文件都是已覆盖已有的,不删除多余的。执行npm run build后dist目录先被删除然后在重新根据配置生成。
        new HtmlWebpackPlugin({      //自动生成一个引入了打包后JS的html
            template: path.resolve(__dirname, './public/index.html'),//模板文件
            filename: 'index.html'//生成的文件名称
        }),
    ], 
}

webpack.dev.js

const merge = require("webpack-merge")
const base = require("./webpack.base")
module.exports = merge(base,{
    devServer:{
        contentBase:'./dist',    //服务器启动的目录
        open:true,   
        proxy:{    //设置代理,可用于本地mock数据,本地自己启动另外一个服务
            // "/api":{
            //     target:"http://localhost:9000"
            // }
        },
        // port:9000, //指定端口号 默认8080
        // hotOnly:true
    },  
})

webpack.prod.js

const merge = require('webpack-merge');
const base = require('./webpack.base');
module.exports = merge(base, {
    // 方便追踪源代码错误
    //(如果不需要该的追踪功能,可以注释掉下行代码)
    devtool: 'source-map'
});

拆分完成后修改package.js
--config 指定文件 默认 webpack.config.js

  "scripts": {
    "build": "webpack --mode production --config webpack.prod.js",
    "dev": "webpack-dev-server --open --hot  --mode development --config webpack.dev.js"
  },

6.6 ES6 转 ES5

  • 安装插件

npm install babel-loader @babel/core @babel/preset-env --save-dev
npm install @babel/plugin-transform-runtime @babel/plugin-transform-modules-commonjs --save-dev
npm install @babel/runtime --save

webpack.base.js

    module:{
        rules:[
            {
                // es6转es5
                test: /.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: [
                            '@babel/plugin-transform-runtime',
                            '@babel/plugin-transform-modules-commonjs'
                        ]
                    }
                }
            },
        ]
    }

6.7 加载css配置(以stylus为例)

  • 安装插件

npm install style-loader css-loader --save-dev
npm install stylus-loader stylus --save-dev

webpack.base.js

   module:{
        rules:[
            {
                // es6转es5
                test: /.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: [
                            '@babel/plugin-transform-runtime',
                            '@babel/plugin-transform-modules-commonjs'
                        ]
                    }
                }
            },
            /**
             * 处理css模块需要两个loader:style-loader和css-loader
             * css-loader工作机制:处理css模块,识别合并css模块
             * style-loader工作机制:把合并的css模块放到html中head的style标签中。
             */
            {
                test: /.css$/,
                use: [
                    //执行顺序:从下到上,从右到左
                    'style-loader', //把合并的css放到style标签
                    'css-loader' //先识别css并合并为一个css
                ]
            },
            /**
             * 处理stylus文件需要style-loader、css-loader、stylus-loader,
             * stylus-loaderr工作机制:把stylus语法转换成css,
            */
            {
                test: /.styl$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'stylus-loader'
                ]
            }
        ]
    }

执行build后,样式代码会直接打包插入到html文件中。

6.8抽离css

安装MiniCssExtractPlugin
npm install mini-css-extract-plugin --save-dev

修改webpack.base.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');  
    //插件
    plugins: [
        // new VueLoaderPlugin(),
        new CleanWebpackPlugin(), //每次在打包时,文件都是已覆盖已有的,不删除多余的。执行npm run build后dist目录先被删除然后在重新根据配置生成。
        new HtmlWebpackPlugin({      //自动生成一个引入了打包后JS的html
            template: path.resolve(__dirname, './public/index.html'),//模板文件
            filename: 'index.html'//生成的文件名称
        }),
        //如果不想让css放在header中style标签中,我们可以使用插件来帮我们抽离css并打包输出到dist目录,此时需要去掉'style-loader'
        new MiniCssExtractPlugin({
            filename: '[name].css',        //输出文件名 
            chunkFilename: '[id].css',    //模块名
        }),
    ],
        module:{
        rules:[
            {
                // es6转es5
                test: /.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: [
                            '@babel/plugin-transform-runtime',
                            '@babel/plugin-transform-modules-commonjs'
                        ]
                    }
                }
            },
            /**
             * 处理css模块需要两个loader:style-loader和css-loader
             * css-loader工作机制:处理css模块,识别合并css模块
             * style-loader工作机制:把合并的css模块放到html中head的style标签中。
             */
            {
                test: /.css$/,
                use: [
                    //执行顺序:从下到上,从右到左
                    MiniCssExtractPlugin.loader, //抽离css替换掉style-load
                    // 'style-loader', //把合并的css放到style标签
                    'css-loader' //先识别css并合并为一个css
                ]
            },
            /**
             * 处理stylus文件需要style-loader、css-loader、stylus-loader,
             * stylus-loaderr工作机制:把stylus语法转换成css,
            */
            {
                test: /.styl$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'stylus-loader'
                ]
            }
        ]
    }

同时在main.js中引入css样式
此时执行 npm run build 后会在dist中生成以下文件

6.9 加载图片资源

安装插件 npm install file-loader url-loader --save-dev

            {
              test: /.(png|svg|jpg|gif|webp)$/,
              use: [
                  {
                      loader: 'url-loader',
                      options: {
                        name:"[name]-[hash].[ext]",//[]表示占位符,name表示源文件的名字,ext是源文件的后缀,hash是复制的文件名入‘570e69d9e57c7d0203b5e30a9dd1dbdf’
                        // outputPath:"images/",    //配置输出位置
                          // 图片输出的实际路径(相对于dist)
                          outputPath: 'images',
                          // 当小于某KB时转为base64
                          limit: 2048,
                          esModule: false //作用是启用CommonJS模块语法 ,否则图片地址可能会出现下方情况
                      }
                  }
              ]
           }

6.10 集成jQuery

安装 npm install jquery --save

//添加
	const webpack = require('webpack');
    plugins: [
        new webpack.ProvidePlugin({
               $: 'jquery',
               jQuery: 'jquery'
           }),
    ], 

6.11 解析vue

安装 npm install -D vue-loader vue-template-compiler
webpack.base.js

const VueLoaderPlugin = require('vue-loader/lib/plugin') //引入
    plugins: [
        new VueLoaderPlugin()
    ], 
    module:{
      rules:[
              //    解析vue
             {
              test: /.vue$/,
              loader: 'vue-loader'
            }
      ]
    }    

7、vue搭建

7.1 引入vue

npm install vue

// import Vue from "vue/dist/vue.js" //写法2
import Vue from "vue" //写法1
import "./assets/reset.css"
//
// console.log(vue)
var app = new Vue({
    el:"#app",
    data:{
        message:"没毛病"
    }
})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webpack--vue</title>
</head>
<body>
    <div id="app">老铁 {{message}}</div>
</body>
</html>
  • 这里直接按照 写法1 引入vue后会报错:

原因: 这里引入的其实不是vue.js 而是vue.common.js。package.json 中的 main 属性决定了,当项目被引入时,输出的是哪个文件,而 vue 的 package.json 中的 main 指向的是 dist/vue.common.js。


解决方法:

1.按照 写法2 引入vue
2、按照 写法1 引入vue 的同时 配置webpack.base.js别名配置

    //别名配置
    resolve: {
        alias: {
            'vue': 'vue/dist/vue.js'
        }
    },

至此,会在页面输出 “老铁 没毛病”。

7.2 挂载APP页面

// import Vue from "vue/dist/vue.js"
import Vue from "vue"
import APP from "./APP.vue"
import "./assets/reset.css"
new Vue({
    render: h => h(APP)
}).$mount("#app");

7.3 配置路由

安装vue-router
npm install vue-router

router/index.js

import Vue from "vue"
import VueRouter from "vue-router"
import Home from "../views/home.vue"
Vue.use(VueRouter)
const routes=[
    {
        path:"/home",
        name:"home",
        component:Home,
        children:[
            {
                path:"/home/children",
                name:"children",
                component:()=>import("../views/children.vue")
            }
        ]
    },
    {
        path:"/home/children",
        name:"children",
        component:()=>import("../views/children.vue")
    }
]
const router = new VueRouter({
    mode:"hash",
    base: process.env.BASE_URL,
    routes
})
export default router

7.4 配置axios

安装 npm install axios

axios.js

import axios from "axios"
import QS from "qs"
axios.defaults.baseURL = process.env.NODE_ENV=="development" ? 
"http://10.1.1.175:9001" : ""
// console.log(axios.defaults.baseURL,"vbaseURL")
axios.defaults.timeout = 10000; 
axios.defaults.withCredentials = true //携带cookie 
// 需要后端配置请求头
// header("Access-Control-Allow-Origin","源地址";
// header("Access-Control-Allow-Credentials", "true");
// 请求拦截器
axios.interceptors.request.use(
    config=>{
        // config.headers = Object.assign({}, config.headers, { token: sessionStorage.getItem("token") })
        return config
    },
    error=>{
        return Promise.reject(error)
    }
)
// 响应拦截器
axios.interceptors.response.use(
    res=>{
        console.log(res)
        return res.data
    },
    err=>{
        console.log(err)
    }
)
// get
export function get(url,data){
    if(url.indexOf("?") != -1){ //防止ie浏览器缓存
        url = url + "&n=" + encodeURIComponent(Math.random())
    }else{
        url = url + "?n=" + encodeURIComponent(Math.random())
    }
    return axios.get(url,{params:data})
}
// post
export function post(url,data){
    return axios({
        url:url,
        method:"post",
        data
    })
}
// 表单
// By default, axios serializes JavaScript objects to JSON
export function postForm(url, data = {}) {
    if (typeof data != "object") {
      return
    }
    return axios({
      url: ip + url,
      method: "post",
      headers: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" },
      transformRequest: [
        function(data) {
          let ret = ""
          for (let it in data) {
            ret += encodeURIComponent(it) + "=" + encodeURIComponent(data[it]) + "&"
          }
          return ret
        }
      ],
      data
    })
  }
//   put
export function put(url, data) {
    return axios({
      url: ip + url,
      method: "put",
      data
    })
  }
// delete
export function deletes(url, data) {
    return axios({
      url: ip + url,
      method: "delete",
      data
    })
  }
export default axios

http.js

import {get,post} from "@/utils/axios"
export const login = data => post("/user/login",data)
export const getTree = data => get("/dataOrder/getDestName")

home.vue

  methods: {
    async getTreedata(){
      let tree = await getTree()
      // console.log(tree,"ffffffffffffffffff")
    },
    // getTreedata(){
    //   getTree().then(res=>{
    //     console.log(res)
    //   })
    // }
   }
原文地址:https://www.cnblogs.com/FormerWhite/p/15016243.html