一、说明

之前写了三篇文章,说明了使用 webpack4 如何从 0 构建 vue 开发环境,目的只是了解 vue-cli 做了哪些事情,但实际上 vue-cli 做的事情还是特别多的。

三篇文章的地址:

支持的目标:

  • ES6 语法转换及 polyfill
  • less/css
  • 图片hash
  • dev 与 prod 环境分离
  • html 模板
  • 文件后缀省略引入
  • postcss
  • devServer

二、目录结构

基本的目录结构如下所示:

1.jpg

目录结构说明:

|- dist/ # 输出目录
|- node_modules/ # 依赖
|- public
  |- index.html # html 模板
|- src
  |- assets # 静态资源,存放图片等
  |- components # 子组件
  |- App.vue # vue入口组件
  |- main.css # 全局 css
  |- main.js # 入口 js
|- .gitignore
|- package.json
|- postcss.config.js # postcss 配置文件
|- README.MD
|- webpack.dev.config.js # webpack dev 配置文件
|- webpack.prod.config.js # webpack prod 配置文件
|- yarn-error.log
|- yarn.lock

三、webpack 配置文件

1、webpack.dev.config.js

development 下的配置文件:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
  mode: 'development',
  watch: true,
  entry: {
    'main': './src/main.js'
  },
  output: {
    path: path.resolve('./dist/'),
    filename: '[name].bundle.js'
  },
  resolve: {
    extensions: ['.js', '.vue']
  },
  module: {
    rules: [{
        test: /\.css$/,
        use: [ 
          { loader: 'style-loader', options: { sourceMap: true } },
          { loader: 'css-loader', options: { importLoaders: 1, sourceMap: true } },
          { 
            loader: 'postcss-loader',
            options: {
              sourceMap: true,
            }
          }
        ]
      },
      {
        test: /\.(png|jpg|gif|svg|webp|jpeg)$/,
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name]-[hash].[ext]',
            outputPath: 'images/',
            publicPath: 'images/',
          }
        }]
      },
      {
        test: /\.(js)$/,
        exclude: /(node_modules)/,
        use:{
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
            plugins: ['@babel/transform-runtime']
          }
        }
      },
      {
        test: /\.(vue)$/,
        use: ['vue-loader']
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html'
    }),
    new webpack.HotModuleReplacementPlugin(),
    new VueLoaderPlugin(),
  ],
  devServer: {
    contentBase: path.join(__dirname, 'dist'), // 监听目录
    compress: true, //  gzip 压缩
    port: 8080, // 端口
    hot: true, // 热重载
    inline: true, // 内联模式 通过内置脚本监听热重载
    open: true, // 打开浏览器
  }
}

2、webpack.prod.config.js

生产环境的配置文件

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
  mode: 'production',
  entry: {
    'main': './src/main.js'
  },
  output: {
    path: path.resolve('./dist/'),
    filename: '[name].bundle.js'
  },
  resolve: {
    extensions: ['.js', '.vue']
  },
  module: {
    rules: [{
        test: /\.css$/,
        use: [ 
          { loader: 'style-loader', options: { sourceMap: true } },
          { loader: 'css-loader', options: { importLoaders: 1, sourceMap: true } },
          { 
            loader: 'postcss-loader',
            options: {
              sourceMap: true,
            }
          }
        ]
      },
      {
        test: /\.(png|jpg|gif|svg|webp|jpeg)$/,
        use: [{
          loader: 'file-loader',
          options: {
            name: '[hash].[ext]',
            outputPath: 'images/',
            publicPath: 'images/',
          }
        }]
      },
      {
        test: /\.(js)$/,
        exclude: /(node_modules)/,
        use:{
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
            plugins: ['@babel/transform-runtime']
          }
        }
      },
      {
        test: /\.(vue)$/,
        use: ['vue-loader']
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html'
    }),
    new VueLoaderPlugin(),
  ]
}

四、package.json

{
  "scripts": {
    "watch": "webpack --config ./webpack.dev.config.js",
    "build": "webpack --config ./webpack.prod.config.js",
    "server": "webpack-dev-server",
    "start": "webpack-dev-server --config ./webpack.dev.config.js && webpack --config ./webpack.dev.config.js "
  },
  "dependencies": {
    "@babel/polyfill": "^7.2.5",
    "@babel/runtime": "^7.2.0",
    "vue": "^2.5.21"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/plugin-transform-runtime": "^7.2.0",
    "@babel/preset-env": "^7.2.3",
    "autoprefixer": "^9.4.4",
    "babel-loader": "^8.0.5",
    "css-loader": "^2.1.0",
    "file-loader": "^3.0.1",
    "html-webpack-plugin": "^3.2.0",
    "postcss-loader": "^3.0.0",
    "style-loader": "^0.23.1",
    "vue-loader": "^15.5.1",
    "vue-template-compiler": "^2.5.21",
    "webpack": "^4.28.1",
    "webpack-cli": "^3.2.1",
    "webpack-dev-server": "^3.1.14"
  }
}

五、github

完整目录代码已经 push 到了 github,感兴趣的可以下载看看: