纯webpack4构架+vue3.0 不采用vue-cli来生成

package.json 配置

{
  "name""yuyue",
  "version""1.0.0",
  "description""",
  "main""index.js",
  "scripts": {
    "dev""node ./webpack/server.js",
    "build""node ./webpack/build.js",
    "dll""webpack --progress --config webpack/webpack.dll.js ---"
  },
  "author""",
  "license""ISC",
  "devDependencies": {
    "@babel/core""^7.6.4",
    "@babel/plugin-proposal-class-properties""^7.5.5",
    "@babel/preset-env""^7.6.3",
    "@babel/preset-react""^7.6.3",
    "add-asset-html-webpack-plugin""^3.1.3",
    "amfe-flexible""^2.2.1",
    "assets-webpack-plugin""^3.9.10",
    "autoprefixer""^9.6.5",
    "axios""^0.19.0",
    "babel-loader""^8.0.6",
    "babel-plugin-syntax-dynamic-import""^6.18.0",
    "chalk""^2.4.2",
    "clean-webpack-plugin""^3.0.0",
    "copy-webpack-plugin""^5.0.4",
    "css-hot-loader""^1.4.4",
    "css-loader""^3.2.0",
    "cssnano""^4.1.10",
    "element-ui""^2.12.0",
    "extract-text-webpack-plugin""^4.0.0-beta.0",
    "file-loader""^4.2.0",
    "friendly-errors-webpack-plugin""^1.7.0",
    "fs-extra""^8.1.0",
    "html-loader""^0.5.5",
    "html-webpack-plugin""^3.2.0",
    "inobounce""^0.2.0",
    "inquirer""^7.0.0",
    "less""^3.10.3",
    "less-loader""^5.0.0",
    "lodash""^4.17.15",
    "mini-css-extract-plugin""^0.8.0",
    "mint-ui""^2.2.13",
    "nodemon-webpack-plugin""^4.1.1",
    "number-precision""^1.3.1",
    "optimize-css-assets-webpack-plugin""^5.0.3",
    "ora""^4.0.2",
    "postcss-loader""^3.0.0",
    "progress-bar-webpack-plugin""^1.12.1",
    "qs""^6.9.0",
    "sass-resources-loader""^2.0.1",
    "uglifyjs-webpack-plugin""^2.2.0",
    "url-loader""^2.2.0",
    "vue""^2.6.10",
    "vue-awesome-swiper""^3.1.3",
    "vue-loader""^15.7.1",
    "vue-print-nb""^1.4.0",
    "vue-qriously""^1.1.1",
    "vue-seamless-scroll""^1.1.17",
    "vue-template-compiler""^2.6.10",
    "vuebar""0.0.20",
    "vuex""^3.1.1",
    "walk""^2.3.14",
    "wangeditor""^3.1.1",
    "webpack""^4.41.2",
    "webpack-cli""^3.3.9",
    "webpack-dev-server""^3.8.2",
    "webpack-merge""^4.2.2",
    "webpack-parallel-uglify-plugin""^1.1.2"
  },
  "dependencies": {
    "core-js""^3.3.3",
    "vue-router""^3.1.3"
  }
}
 
{
  "name""yuyue",
  "version""1.0.0",
  "description""",
  "main""index.js",
  "scripts": {
    "dev""node ./webpack/server.js",
    "build""node ./webpack/build.js",
    "dll""webpack --progress --config webpack/webpack.dll.js ---"
  },
  "author""",
  "license""ISC",
  "devDependencies": {
    "@babel/core""^7.6.4",
    "@babel/plugin-proposal-class-properties""^7.5.5",
    "@babel/preset-env""^7.6.3",
    "@babel/preset-react""^7.6.3",
    "add-asset-html-webpack-plugin""^3.1.3",
    "amfe-flexible""^2.2.1",
    "assets-webpack-plugin""^3.9.10",
    "autoprefixer""^9.6.5",
    "axios""^0.19.0",
    "babel-loader""^8.0.6",
    "babel-plugin-syntax-dynamic-import""^6.18.0",
    "chalk""^2.4.2",
    "clean-webpack-plugin""^3.0.0",
    "copy-webpack-plugin""^5.0.4",
    "css-hot-loader""^1.4.4",
    "css-loader""^3.2.0",
    "cssnano""^4.1.10",
    "element-ui""^2.12.0",
    "extract-text-webpack-plugin""^4.0.0-beta.0",
    "file-loader""^4.2.0",
    "friendly-errors-webpack-plugin""^1.7.0",
    "fs-extra""^8.1.0",
    "html-loader""^0.5.5",
    "html-webpack-plugin""^3.2.0",
    "inobounce""^0.2.0",
    "inquirer""^7.0.0",
    "less""^3.10.3",
    "less-loader""^5.0.0",
    "lodash""^4.17.15",
    "mini-css-extract-plugin""^0.8.0",
    "mint-ui""^2.2.13",
    "nodemon-webpack-plugin""^4.1.1",
    "number-precision""^1.3.1",
    "optimize-css-assets-webpack-plugin""^5.0.3",
    "ora""^4.0.2",
    "postcss-loader""^3.0.0",
    "progress-bar-webpack-plugin""^1.12.1",
    "qs""^6.9.0",
    "sass-resources-loader""^2.0.1",
    "uglifyjs-webpack-plugin""^2.2.0",
    "url-loader""^2.2.0",
    "vue""^2.6.10",
    "vue-awesome-swiper""^3.1.3",
    "vue-loader""^15.7.1",
    "vue-print-nb""^1.4.0",
    "vue-qriously""^1.1.1",
    "vue-seamless-scroll""^1.1.17",
    "vue-template-compiler""^2.6.10",
    "vuebar""0.0.20",
    "vuex""^3.1.1",
    "walk""^2.3.14",
    "wangeditor""^3.1.1",
    "webpack""^4.41.2",
    "webpack-cli""^3.3.9",
    "webpack-dev-server""^3.8.2",
    "webpack-merge""^4.2.2",
    "webpack-parallel-uglify-plugin""^1.1.2"
  },
  "dependencies": {
    "core-js""^3.3.3",
    "vue-router""^3.1.3"
  }
}

1基础配置

const path = require(‘path‘);
const fs = require(‘fs-extra‘);
const MiniCssExtractPlugin = require(‘mini-css-extract-plugin‘);
// 取本机IP地址
const getIPAdress = () => {
  var interfaces = require(‘os‘).networkInterfaces();
  for (var devName in interfaces) {
    var iface = interfaces[devName];
    for (var i = 0i < iface.lengthi++) {
      var alias = iface[i];
      if (alias.family === ‘IPv4‘ && alias.address !== ‘127.0.0.1‘ && !alias.internal) {
        return alias.address;
      }
    }
  }
}
//文件是否存在
const isFile = v => {
  return fs.pathExistsSync(v);
}

const [TARGETclientItem= [process.env.npm_lifecycle_eventprocess.argv[2]];

const vueLoader = {
  dev"vue-style-loader",
  buildMiniCssExtractPlugin.loader,
  dllMiniCssExtractPlugin.loader,
};

module.exports = {
  rootpath.resolve(__dirname‘../‘),
  entrypath.resolve(__dirname‘../src/index.js‘),
  publicPath‘‘,
  outPathpath.resolve(__dirname‘../dist‘),
  devServergetIPAdress() || ‘localhost‘,
  port‘6001‘,
  isFileisFile,
  getIPAdressgetIPAdress,
  vueLoadervueLoader[TARGET],
  host:‘0.0.0.0‘
}
const path = require(‘path‘);
const fs = require(‘fs-extra‘);
const MiniCssExtractPlugin = require(‘mini-css-extract-plugin‘);
// 取本机IP地址
const getIPAdress = () => {
  var interfaces = require(‘os‘).networkInterfaces();
  for (var devName in interfaces) {
    var iface = interfaces[devName];
    for (var i = 0i < iface.lengthi++) {
      var alias = iface[i];
      if (alias.family === ‘IPv4‘ && alias.address !== ‘127.0.0.1‘ && !alias.internal) {
        return alias.address;
      }
    }
  }
}
//文件是否存在
const isFile = v => {
  return fs.pathExistsSync(v);
}

const [TARGETclientItem= [process.env.npm_lifecycle_eventprocess.argv[2]];

const vueLoader = {
  dev"vue-style-loader",
  buildMiniCssExtractPlugin.loader,
  dllMiniCssExtractPlugin.loader,
};

module.exports = {
  rootpath.resolve(__dirname‘../‘),
  entrypath.resolve(__dirname‘../src/index.js‘),
  publicPath‘‘,
  outPathpath.resolve(__dirname‘../dist‘),
  devServergetIPAdress() || ‘localhost‘,
  port‘6001‘,
  isFileisFile,
  getIPAdressgetIPAdress,
  vueLoadervueLoader[TARGET],
  host:‘0.0.0.0‘
}

2、webpack 基本配置 webpack.base.js

let HtmlWebpackPlugin = require(‘html-webpack-plugin‘);
let config = require(‘./webpack.config.js‘);
const path = require(‘path‘);
const VueLoaderPlugin = require(‘vue-loader/lib/plugin‘);
const webpack = require(‘webpack‘);
const AddAssetHtmlPlugin = require(‘add-asset-html-webpack-plugin‘);

module.exports = {
  entryconfig.entry,
  output: {
    filename‘bundle.js‘,
    pathconfig.outPath,
    publicPath‘./‘,
    chunkFilename‘[name].vue.js‘
  },
  resolve: {
    alias: {
      ‘lib‘path.join(config.root‘lib/‘),
      ‘@css‘path.join(config.root‘src/css‘),
      ‘vue$‘‘vue/dist/vue.esm.js‘,
    },
    modules: [‘node_modules‘‘*‘],
    extensions: [‘.ts‘‘.tsx‘‘.js‘‘.jsx‘‘.json‘‘.vue‘]
  },
  module: {
    rules: [{
      test: /\.css$/,
      use: [
        config.vueLoader, {
          loader"css-loader"
        }, {
          loader"postcss-loader",
          options: { plugins: [require("autoprefixer")] }
        }
      ]
    },
    {
      test: /\.less$/,
      use: [
        config.vueLoader, {
          loader"css-loader"
        }, {
          loader"postcss-loader",
          options: { plugins: [require("autoprefixer")] }
        }, {
          loader"less-loader"
        }, {
          loader‘sass-resources-loader‘,
          options: {
            resourcespath.join(config.root‘src/css/base.less‘),
          }
        }
      ]
    },
    {
      test: /\.vue$/,
      loader‘vue-loader‘,
      options: {
        transformAssetUrls: {
          video: [‘src‘‘poster‘],
          source‘src‘,
          img‘src‘,
          image‘xlink:href‘
        },
        compilerOptions: {
          preserveWhitespacefalse
        }
      }
    },
    {
      test: /\.js$/,
      use: {
        loader‘babel-loader‘,
        options: {
          plugins: [‘@babel/plugin-proposal-class-properties‘‘syntax-dynamic-import‘]
        }
      },
      exclude: /node_modules/,
      // include: [process.cwd(), ‘./src‘]
    },
    {
      test: /\.(gif|png|jpe?g|svg|ico)$/i,
      use: [{
        loader‘url-loader‘
      },
      ]
    },
    {
      test: /\.(woff|woff2|eot|ttf|otf)$/,   // 处理字体
      use: {
        loader‘file-loader‘
      }
    }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
    new webpack.DllReferencePlugin({
      context__dirname,
      manifestrequire(‘./vendor/vue-manifest.json‘)
    }),
    new HtmlWebpackPlugin({
      filename`index.html`,
      templateconfig.root + ‘/src/index.html‘,
      title‘wyulang‘,
      prodtrue,
      hashtrue,
      minify: {
        removeAttributeQuotestrue,
        collapseWhitespacetrue,
        html5true,
        minifyCSStrue,
        removeCommentstrue,
        removeEmptyAttributestrue
      }
    }),
    new AddAssetHtmlPlugin({
      filepathpath.resolve(__dirname‘./vendor/vue.library.js‘),
    })
  ]
}

3、webpack 开发环境配置  webpack.dev.js

const ProgressBarPlugin = require(‘progress-bar-webpack-plugin‘);
const FriendlyErrorsPlugin = require(‘friendly-errors-webpack-plugin‘);
const webpackbase = require(‘./webpack.base.js‘);
const webpack = require(‘webpack‘);
const merge = require(‘webpack-merge‘);
let config = require(‘./webpack.config.js‘);
const chalk = require(‘chalk‘);
const NodemonPlugin = require(‘nodemon-webpack-plugin‘);


let webpackDevConfig = {
  devtool‘source-map‘,
  mode‘development‘,
  devServer: {
    openfalse,
    contentBaseconfig.outPath,
    publicPath"/",
    hottrue,
    noInfotrue,
    portconfig.port,
    hostconfig.host,
    historyApiFallback: {
      index‘/index.html‘ //与output的publicPath有关(HTMLplugin生成的html默认为index.html)
    }
  },
  plugins: [
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new FriendlyErrorsPlugin({
      compilationSuccessInfo: {
        messages: [chalk.cyan.bold(‘Your application is running here: ‘+ chalk.greenBright.bold(`http://${config.devServer}:${config.port}/`)]
      }
    }),
    new ProgressBarPlugin(
      {
        formatchalk.blueBright(‘  build :bar :percent (:elapsed seconds) ‘),
        cleartrue,
        summaryfalse,
        customSummaryres => {
          process.stderr.write(chalk.blueBright(‘   ‘))
        }
      }
    ),
    // new NodemonPlugin()
  ]
}

module.exports = merge(webpackbasewebpackDevConfig)

4、webpack 生产打包环境配置 webpack.prod.js

const merge = require(‘webpack-merge‘);
const webpackbase = require(‘./webpack.base.js‘);
const MiniCssExtractPlugin = require(‘mini-css-extract-plugin‘);
const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin‘);
const OptimizeCssAssetsPlugin = require(‘optimize-css-assets-webpack-plugin‘);
const chalk = require(‘chalk‘);
const { CleanWebpackPlugin } = require(‘clean-webpack-plugin‘);
const config = require(‘./webpack.config.js‘);
const HtmlWebpackPlugin = require(‘html-webpack-plugin‘);
const ParallelUglifyPlugin = require(‘webpack-parallel-uglify-plugin‘);
const _version = new Date().getTime();

const webpackProdConfig = {
  devtool‘inline-cheap-source-map‘,
  mode‘production‘,
  optimization: {
    noEmitOnErrorstrue,
    minimizer: [
      new UglifyJsPlugin({
        cachetrue,
        paralleltrue,
        sourceMapfalse // set to true if you want JS source maps
      }),
      new OptimizeCssAssetsPlugin({
        cssProcessorrequire(‘cssnano‘)
      })
    ],
    splitChunks: {
      chunks‘all‘
    }
  },
  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename`[name].${_version}.css`,
      chunkFilename`[name].${_version}.css`,
    }),
    new ProgressBarPlugin(
      {
        formatchalk.blueBright(‘ build :bar :percent (:elapsed seconds) ‘),
        clearfalse,
        summaryfalse,
        customSummaryres => {
          process.stderr.write(chalk.blueBright.bold(` build end use time ${res} \n`))
        }
      }
    ),
  ]
}

module.exports = merge(webpackbasewebpackProdConfig)

5、webpack 公共库环境配置 webpack.dll.js

‘use strict‘

const path = require(‘path‘)
const webpack = require(‘webpack‘)
const { CleanWebpackPlugin } = require(‘clean-webpack-plugin‘)
const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin‘);
let config = require(‘./webpack.config.js‘);

let webpackDll = {
  mode‘production‘,
  entry: {
    vue: [
      ‘vue/dist/vue.esm.js‘,
      ‘vuex‘,
      ‘axios‘,
      ‘vue-router‘
    ]
  },
  output: {
    pathpath.join(__dirname‘../webpack/vendor/‘), // 生成的文件存放路径
    filename‘[name].library.js‘// 生成的文件名字(默认为dll.vendor.[hash].js)
    library‘[name]_library‘ // 生成文件的映射关系,与下面DllPlugin中配置对应
  },
  optimization: {
    noEmitOnErrorstrue,
    minimizer: [
      new UglifyJsPlugin({
        cachetrue,
        paralleltrue,
        sourceMapfalse // set to true if you want JS source maps
      })
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new webpack.DllPlugin({
      pathpath.join(__dirname‘../webpack/vendor/[name]-manifest.json‘),
      name‘[name]_library‘// 与上面output中配置对应
      context__dirname // 上下文环境路径(必填,为了与DllReferencePlugin存在与同一上下文中)
    })
  ]
}
module.exports = webpackDll;

6、server启动配置 server.js

const webpack = require("webpack");
const webpackConfig = require("./webpack.dev.js");
let WebpackDevServer = require(‘webpack-dev-server‘);
let config = require(‘./webpack.config.js‘);


const compiler = webpack(webpackConfig);
const devServerOptions = Object.assign({}, webpackConfig.devServer);
const server = new WebpackDevServer(compilerdevServerOptions);


server.listen(config.portconfig.hostres => {});

7、打包配置 build.js

const webpack = require(‘webpack‘// 加载 webpack
const webpackConfig = require("./webpack.prod.js");
const chalk = require(‘chalk‘);
const ora = require(‘ora‘);

process.stderr.write(chalk.blueBright.bold(` build start ..... \n\n`));
webpack(webpackConfig, (errstate=> {});


第一次启动 之前先运行一次 npm run dll

启动命令

npm run dev

打包命令

npm run build

 完整项目gitHub地址  https://github.com/wyulang/vue4