webpack构建vue项目 基础07之开发环境、生产环境、配置的抽离

webpack构建vue项目 基础07之开发环境、生产环境、配置的抽离

01:webpack构建vue项目 基础07之开发环境 - 开发服务器 ( 实现页面刷新)

package.json

  • 修改点:"dev": "webpack-dev-server --mode development",
  • 修改点:"webpack-dev-server": "^3.2.1"
  "scripts": {
    "dev": "webpack-dev-server --mode development",
    "build": "webpack --mode production",
  },
 "devDependencies": {
    "webpack": "^4.29.6",
    "webpack-cli": "^3.2.3",
    "webpack-dev-server": "^3.2.1"
  }

webpack.config.js

module.exports = {
  // webpack执行打包的唯一入口
  entry: {
    main: [path.resolve(__dirname, './src/main.js')],
  },
  // 打包的输入
  output: {
    publicPath: '', //
    // 将所有依赖的模块合并输出到main_xxxxxx.js,xxxxxx为随机生成的6位hash码
    //当内容有改变时,hash会变化,防止缓存原因导致修改不更新
    filename: 'js/[name]_[contenthash:6].js',
    // 输出文件的存放路径, 必须是绝对路径
    path: path.resolve(__dirname, "./dist")

  },
  // 本地开发环境配置
  devServer: {
    contentBase: path.resolve(__dirname, "./dist"), //指定被访问html页面所在的目录的
    open: true, // 指运行npm run server指令后,自动在浏览器里打开一个页面
    port: 8081, // 指定打开的页面的端口为8081,也可以指定其他端口
    inline: true, // 页面实时刷新
    // host:"127.0.0.1" // 地址 http://127.0.0.1:8081/
    overlay: true, // 如果代码出错,会在浏览器页面弹出“浮动层”。类似于 vue-cli 等脚手架
    proxy: {
      // 跨域代理转发
      '/api': {
        target: 'http://102.03.34.58',
        pathRewrite: {
          '^/api': ''
        }
      }
    },
    historyApiFallback: {
      // HTML5 history模式
      rewrites: [{
        from: /.*/,
        to: '/index.html'
      }]
    }
  },
}

mian.js

// 全局引入
// import '@babel/polyfill'
console.log("main");
import {
  age
} from "./person"
console.log("age", age);
let a = 10;
console.log("a", a);
const set = new Set([1, 2, 3, 1])
console.log('res,', set, '; set-arr', [...set]) // res, Set(3) {1, 2, 3} ; set-arr (3) [1, 2, 3]
import "./css/main.css"
import "./css/index.scss"
import {
  add
} from "./utils/index"
console.log("add", add(2, 2)); // add 4
import _ from "lodash"
console.log("使用lodash", _.add(22, 33)); // 使用lodash 55

import Vue from "vue"
import App from "./App.vue";

const app = new Vue({
  el:'#app',
  render: (h) => h(App), //h就是vue中的createApp参数
})

App.vue

<template>
  <div id="app">
    <div class="bg">msg - {{ msg }}</div>
    <div class="box">我是box-11-1</div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      msg: 'msg-msg-1'
    }
  }
}
</script>
<style scoped>
#app {
  font-size: 40px;
}
.bg {
  background: yellow;
}
.box{
  width: 100px;
  height: 100px;
  background: pink;
  font-size: 20px;
}
</style>

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div id="app">
  </div>
</body>
</html>

npm run dev 效果

  • 于终端起一个服务,点击链接,可加载出开发时的代码效果
    在这里插入图片描述

  • 页面效果
    在这里插入图片描述

npm run build 效果

在这里插入图片描述
在这里插入图片描述

02:webpack构建vue项目 基础07之 开发环境、生产环境的抽离

package.json

  "scripts": {
    "dev": "webpack-dev-server --config ./build/webpack.config.dev.js",
    "build": "webpack --config ./build/webpack.config.prod.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "webpack-merge": "^4.2.1"
  },

02-1:抽离基础配置 build / webpack.config.base.js

const path = require("path");
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 将 css 单独打包成文件
const HtmlWebpackPlugin = require('html-webpack-plugin') // 自动引入文件 插件
const {
  CleanWebpackPlugin
} = require('clean-webpack-plugin') // 版本为2.0.0 不需要 { CleanWebpackPlugin } 结构! 大于2.0.0则需要

module.exports = {
  // webpack执行打包的唯一入口
  entry: {
    // main: [path.resolve(__dirname, './src/main.js')],
    main: "./src/main.js"
  },
  // 打包的输入
  output: {
    publicPath: '', //
    // 将所有依赖的模块合并输出到main_xxxxxx.js,xxxxxx为随机生成的6位hash码
    //当内容有改变时,hash会变化,防止缓存原因导致修改不更新
    filename: 'js/[name]_[contenthash:6].js',
    // 输出文件的存放路径, 必须是绝对路径
    path: path.resolve(__dirname, "../dist") // path.resolve(__dirname, "./dist")

  },
  // loader相关配置
  module: {
    rules: [{
        test: /\.(sa|sc|c)ss$/, // 针对 .sass .scss 或者 .css 后缀的文件设置 loader
        use: [{
            loader: "vue-style-loader"
          },
          // MiniCssExtractPlugin.loader,
          {
            loader: MiniCssExtractPlugin.loader
          },
          'css-loader',
          'postcss-loader', // 使用 postcss 为 css 加上浏览器前缀
          'sass-loader' // 使用 sass-loader 将 scss 转为 css
        ]
      },
      {
        test: /\.js$/, // 使用正则来匹配 js 文件
        exclude: /node_modules/, // 排除依赖包文件夹
        use: {
          loader: 'babel-loader' // 使用 babel-loader
        }
      },
      {
        test: /\.(png|jpg|jpeg|gif|webp)$/,
        use: [{
            loader: 'url-loader',
            options: {
              name: '[name]-[hash:5].min.[ext]',
              outputPath: 'images/', //输出到 images 文件夹
              limit: 20000 //把小于 20kb 的文件转成 Base64 的格式
            }
          },
          // 使用 image-webpack-loader 对图片进行压缩
          {
            loader: "image-webpack-loader",
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: '65-90',
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              webp: {
                quality: 75
              }
            }
          },
        ]
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
    ]
  },
  resolve: {
    extensions: ['.js', '.css', '.scss', '.vue', '.json'], // 引入的时候 可以省略后缀
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  plugins: [
    //默认情况下,此插件删除 webpack output.path目录中的所有文件,以及每次成功重建后所有未使用的 webpack 资产
    new CleanWebpackPlugin(),
    // 自动生成html ( 于打包后 dist目录下的 双击在浏览器显示 )
    new HtmlWebpackPlugin({
      // 打包输出HTML
      title: '自动生成 HTML',
      minify: {
        // 压缩 HTML 文件
        removeComments: true, // 移除 HTML 中的注释
        collapseWhitespace: true, // 删除空白符与换行符
        minifyCSS: true // 压缩内联 css
      },
      filename: 'index.html', // 生成后的文件名
      template: 'index.html', // 根据此模版生成 HTML 文件
      // chunks: ['main'] // entry中的 app 入口才会被打包
    }),
    // 分割css
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css'
    }),
  ]
}

02-2:抽离开发环境 build / webpack.config.js

const path = require("path");
const merge = require("webpack-merge")
const baseConfig = require("./webpack.config.base")
const devConfig = {
  output: {
    filename: '[name].js',
    chunkFilename: '[name].js'
  },
  mode: 'development',
  devtool: 'source-map', // 调试源码
  // 本地开发环境配置
  devServer: {
    contentBase: path.resolve(__dirname, "../dist"), //指定被访问html页面所在的目录的
    open: true, // 指运行npm run server指令后,自动在浏览器里打开一个页面
    port: 8081, // 指定打开的页面的端口为8081,也可以指定其他端口
    inline: true, // 页面实时刷新
    // host:"127.0.0.1" // 地址 http://127.0.0.1:8081/
    overlay: true, // 如果代码出错,会在浏览器页面弹出“浮动层”。类似于 vue-cli 等脚手架
    proxy: {
      // 跨域代理转发
      '/api': {
        target: 'http://102.03.34.58',
        pathRewrite: {
          '^/api': ''
        }
      }
    },
    // historyApiFallback: true
    historyApiFallback: {
      // HTML5 history模式
      rewrites: [{
        from: /.*/,
        to: '/index.html'
      }]
    }
  },
  // module: {
  //   rules: [{
  //     test: /\.(sa|sc|c)ss$/, // 针对 .sass .scss 或者 .css 后缀的文件设置 loader
  //     use: [
  //       'style-loader',
  //       {
  //         loader: "vue-style-loader"
  //       },
  //       {
  //         loader: MiniCssExtractPlugin.loader
  //       },
  //       'css-loader',
  //       'postcss-loader', // 使用 postcss 为 css 加上浏览器前缀
  //       'sass-loader' // 使用 sass-loader 将 scss 转为 css
  //     ]
  //   }]
  // }
}
module.exports = merge(baseConfig, devConfig)

02-3:抽离生产环境 build/webpack.config.js

const path = require("path");
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 将 css 单独打包成文件
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') // 压缩 css
const HtmlWebpackPlugin = require('html-webpack-plugin') // 自动引入文件 插件
const {
  CleanWebpackPlugin
} = require('clean-webpack-plugin') // 版本为2.0.0 不需要 { CleanWebpackPlugin } 结构! 大于2.0.0则需要

// 去掉 不加载的css
const PurifyCSS = require('purifycss-webpack')
const glob = require('glob-all')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); //压缩js

const merge = require("webpack-merge")
const baseConfig = require("./webpack.config.base")

const prodConfig = {
  mode: 'production',
  // 代码切片相关
  optimization: {
    // 代码切片 分割 打包后分割为多个 .js文件
    splitChunks: {
      chunks: 'all',
      // 打包后的效果
      // js/lodash_950848.js  71.1 KiB       0  [emitted]  lodash
      // js/main_63de8b.js  1.78 KiB       1  [emitted]  main
      // js/vendors~main_2938f3.js   112 KiB       2  [emitted]  vendors~main
      cacheGroups: {
        lodash: {
          name: 'lodash',
          test: /[\\/]node_modules[\\/]lodash[\\/]/,
          priority: 5 // 优先级要大于 vendors 不然会被打包进 vendors
        },
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10 // 打包node_modules
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    },

  },
  plugins: [
    //默认情况下,此插件删除 webpack output.path目录中的所有文件,以及每次成功重建后所有未使用的 webpack 资产
    new CleanWebpackPlugin(),
    // 清除无用 css
    new PurifyCSS({
      paths: glob.sync([
        // 要做 CSS Tree Shaking 的路径文件
        path.resolve(__dirname, './*.html'), // 请注意,我们同样需要对 html 文件进行 tree shaking
        path.resolve(__dirname, './src/*.js')
      ])
    }),
    // // 分割css
    // new MiniCssExtractPlugin({
    //   filename: '[name].css',
    //   chunkFilename: '[id].css'
    // }),
    // 压缩css
    new OptimizeCssAssetsPlugin({
      assetNameRegExp: /\.optimize\.css$/g,
      cssProcessor: require('cssnano'),
      cssProcessorPluginOptions: {
        preset: ['default', {
          discardComments: {
            removeAll: true
          }
        }],
      },
      canPrint: true
    }),
    // 压缩js
    new UglifyJsPlugin(),
  ]
}
module.exports = merge(baseConfig, prodConfig)

App.vue

<template>
  <div id="app">
    <div class="bg">msg - {{ msg }}</div>
    <div class="box">我是box-11-1-111-1</div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      msg: 'msg-msg-1'
    }
  }
}
</script>
<style scoped>
#app {
  font-size: 40px;
}
.bg {
  background: yellow;
}
.box{
  width: 100px;
  height: 100px;
  background: pink;
  font-size: 20px;
}
</style>

mian.js

// 全局引入
// import '@babel/polyfill'
console.log("main");
import {
  age
} from "./person"
console.log("age", age);
let a = 10;
console.log("a", a);
const set = new Set([1, 2, 3, 1])
console.log('res,', set, '; set-arr', [...set]) // res, Set(3) {1, 2, 3} ; set-arr (3) [1, 2, 3]
import "./css/main.css"
import "./css/index.scss"
import {
  add
} from "./utils/index"
console.log("add", add(2, 2)); // add 4
import _ from "lodash"
console.log("使用lodash", _.add(22, 33)); // 使用lodash 55

import Vue from "vue"
import App from "./App.vue";

const app = new Vue({
  el:'#app',
  render: (h) => h(App), //h就是vue中的createApp参数
})

npm run dev 效果

在这里插入图片描述

npm run build 效果

在这里插入图片描述

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div id="app">
  </div>
</body>
</html>

.babelrc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ],
  "plugins": ["@babel/plugin-transform-runtime"]
}

postcss.config.js

module.exports = {
  plugins: [
    require('autoprefixer')
    // , require('postcss-pxtorem')({
    //   remUnit: 50, // 50px = 1rem
    //   remPrecision: 2 // rem的小数点后位数
    // })
  ]
}

css

mian.css
body {
  /* background: yellow; */
   /* 29kb  效果 background: url(images/dog1-afa6a.min.webp); */
  background: url("../img/dog.webp");
  /* 4.4kb 效果 background: url(data:image/webp;base64,UklGRpYRA。。。。 */
  /* background: url("../img/hlw.webp") */
  /* 注意点:配置了图片的大小压缩 小于20kb 转化为base64 */
}

index.scss
$bgColor: red !default;
html {
  p {
    background-color: $bgColor;
  }
  .ppp {
    display: flex;
    justify-content: flex-end;
    color: #fff;
    font-size: 16px;
    border: 2px solid #ccc;
  }
  .box {
    width: 100px;
    height: 100px;
    border: 2px solid red;
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值