美文网首页
vue2.0 cli +webpack 多入口开发 配置教程附详

vue2.0 cli +webpack 多入口开发 配置教程附详

作者: 凉介Seven | 来源:发表于2018-09-29 20:09 被阅读0次

    我们平常用vue开发的时候总觉得vue好像就是专门为了单页面应用而诞生的,其实不是。因为vue在工程化开发的时候很依赖webpack,而webpack是将所有的资源整合到一块,弄成一个单页面。但是vue不止可以做单页面,它还可以做多页面,如果要做多页面的话需要对他的依赖,也就是webpack就是重新配置才可以。

    vue的开发有两种,一种是直接的在script标签里引入vue.js文件即可,这样子引入的话个人感觉做小型的多页面会比较舒坦,一旦做大型一点的项目,还是离不开webpack。所以另一种方法也就是基于webpack和vue-cli的工程化开发。下面详解步骤。

    先声明,如果用vue进行工程化开发,首先要有node.js,然后再下一个npm,不过一般新版的node都会有npm所以可以不用弄。指令是在命令行里输入。首先第一步就是生成一个vue项目,用指令:

    vue init webpack test
    

    博主本人声明的文件名为test,下载好后一路enter,之后便生成了一个vue项目,但是这个vue项目还没有一些相关的依赖,这个时候需要进入到该文件夹里面,输入npm install速不好,则用cnpm install,效果一样。略等几分钟后整个依赖便已经下完,之后输入指令:

    npm run dev
    

    则会自动打开一个界面,如果报错不能打开网页的话只有一种原因,那就端口占用,这个时候需要到/config/index.js目录下改端口就行。
    当一个vue项目完成好所有的配置后,接下来就是我们的重点了,

    glob是webpack安装时依赖的一个第三方模块,还模块允许你使用 *等符号,后面配置需要用到先安装上

    npm i glob
    
    项目目录 image.png

    需要修改的文件


    image.png

    utils

    // utils.js文件
    
    var path = require('path')
    var config = require('../config')
    var ExtractTextPlugin = require('extract-text-webpack-plugin')
    
    exports.assetsPath = function (_path) {
      var assetsSubDirectory = process.env.NODE_ENV === 'production' ?
        config.build.assetsSubDirectory :
        config.dev.assetsSubDirectory
      return path.posix.join(assetsSubDirectory, _path)
    }
    
    exports.cssLoaders = function (options) {
      options = options || {}
    
      var cssLoader = {
        loader: 'css-loader',
        options: {
          minimize: process.env.NODE_ENV === 'production',
          sourceMap: options.sourceMap
        }
      }
    
      // generate loader string to be used with extract text plugin
      function generateLoaders (loader, loaderOptions) {
        var loaders = [cssLoader]
        if (loader) {
          loaders.push({
            loader: loader + '-loader',
            options: Object.assign({}, loaderOptions, {
              sourceMap: options.sourceMap
            })
          })
        }
    
        // Extract CSS when that option is specified
        // (which is the case during production build)
        if (options.extract) {
          return ExtractTextPlugin.extract({
            use: loaders,
            fallback: 'vue-style-loader'
          })
        } else {
          return ['vue-style-loader'].concat(loaders)
        }
      }
    
      // https://vue-loader.vuejs.org/en/configurations/extract-css.html
      return {
        css: generateLoaders(),
        postcss: generateLoaders(),
        less: generateLoaders('less'),
        sass: generateLoaders('sass', { indentedSyntax: true }),
        scss: generateLoaders('sass'),
        stylus: generateLoaders('stylus'),
        styl: generateLoaders('stylus')
      }
    }
    
    // Generate loaders for standalone style files (outside of .vue)
    exports.styleLoaders = function (options) {
      var output = []
      var loaders = exports.cssLoaders(options)
      for (var extension in loaders) {
        var loader = loaders[extension]
        output.push({
          test: new RegExp('\\.' + extension + '$'),
          use: loader
        })
      }
      return output
    }
    
    /* 这里是添加的部分 ---------------------------- 开始 */
    
    // glob是webpack安装时依赖的一个第三方模块,还模块允许你使用 *等符号, 例如lib/*.js就是获取lib文件夹下的所有js后缀名的文件
    var glob = require('glob')
    // 页面模板
    var HtmlWebpackPlugin = require('html-webpack-plugin')
    // 取得相应的页面路径,因为之前的配置,所以是src文件夹下的pages文件夹
    var PAGE_PATH = path.resolve(__dirname, '../src/pages')
    // 用于做相应的merge处理
    var merge = require('webpack-merge')
    
    
    //多入口配置
    // 通过glob模块读取pages文件夹下的所有对应文件夹下的js后缀文件,如果该文件存在
    // 那么就作为入口处理
    exports.entries = function () {
      var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
      var map = {}
      entryFiles.forEach((filePath) => {
        var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
        map[filename] = filePath
      })
      return map
    }
    
    //多页面输出配置
    // 与上面的多页面入口配置相同,读取pages文件夹下的对应的html后缀文件,然后放入数组中
    exports.htmlPlugin = function () {
      let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
      let arr = []
      entryHtml.forEach((filePath) => {
        let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
        let conf = {
          // 模板来源
          template: filePath,
          // 文件名称
          filename: filename + '.html',
          // 页面模板需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本
          chunks: ['manifest', 'vendor', filename],
          inject: true
        }
        if (process.env.NODE_ENV === 'production') {
          conf = merge(conf, {
            minify: {
              removeComments: true,
              collapseWhitespace: true,
              removeAttributeQuotes: true
            },
            chunksSortMode: 'dependency'
          })
        }
        arr.push(new HtmlWebpackPlugin(conf))
      })
      return arr
    }
    /* 这里是添加的部分 ---------------------------- 结束 */
    

    webpack.base.conf.js

    // webpack.base.conf.js 文件
    
    var path = require('path')
    var utils = require('./utils')
    var config = require('../config')
    var vueLoaderConfig = require('./vue-loader.conf')
    
    function resolve (dir) {
      return path.join(__dirname, '..', dir)
    }
    
    module.exports = {
      /* 修改部分 ---------------- 开始 */
      entry: utils.entries(),
      /* 修改部分 ---------------- 结束 */
      output: {
        path: config.build.assetsRoot,
        filename: '[name].js',
        publicPath: process.env.NODE_ENV === 'production' ?
          config.build.assetsPublicPath :
          config.dev.assetsPublicPath
      },
      resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
          'pages': resolve('src/pages'),
          'components': resolve('src/components')
        }
      },
      module: {
        rules: [{
          test: /\.vue$/,
          loader: 'vue-loader',
          options: vueLoaderConfig
        },
        {
          test: /\.js$/,
          loader: 'babel-loader',
          include: [resolve('src'), resolve('test')]
        },
        {
          test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: utils.assetsPath('img/[name].[hash:7].[ext]')
          }
        },
        {
          test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
          }
        }
        ]
      }
    }
    

    webpack.dev.conf.js

    var utils = require('./utils')
    var webpack = require('webpack')
    var config = require('../config')
    var merge = require('webpack-merge')
    var baseWebpackConfig = require('./webpack.base.conf')
    var HtmlWebpackPlugin = require('html-webpack-plugin')
    var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
    
    // add hot-reload related code to entry chunks
    // Object.keys(baseWebpackConfig.entry).forEach(function (name) {
    //  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
    // })
    
    // add hot-reload related code to entry chunks
    Object.keys(baseWebpackConfig.entry).forEach(function (name) {
      baseWebpackConfig.entry[name] = baseWebpackConfig.entry[name]
    })
    
    module.exports = merge(baseWebpackConfig, {
      module: {
        rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
      },
      // cheap-module-eval-source-map is faster for development
      devtool: '#cheap-module-eval-source-map',
      plugins: [
        new webpack.DefinePlugin({
          'process.env': {
            NODE_ENV: '"production"'
          }
        }),
        // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoEmitOnErrorsPlugin(),
        // https://github.com/ampedandwired/html-webpack-plugin
        /* 注释这个区域的文件 ------------- 开始 */
        // new HtmlWebpackPlugin({
        //  filename: 'index.html',
        //  template: 'index.html',
        //  inject: true
        // }),
        /* 注释这个区域的文件 ------------- 结束 */
        new FriendlyErrorsPlugin()
    
        /* 添加 .concat(utils.htmlPlugin()) ------------------ */
      ].concat(utils.htmlPlugin())
    })
    

    webpack.prod.conf.js

    var path = require('path')
    var utils = require('./utils')
    var webpack = require('webpack')
    var config = require('../config')
    var merge = require('webpack-merge')
    var baseWebpackConfig = require('./webpack.base.conf')
    var CopyWebpackPlugin = require('copy-webpack-plugin')
    var HtmlWebpackPlugin = require('html-webpack-plugin')
    var ExtractTextPlugin = require('extract-text-webpack-plugin')
    var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
    
    var env = config.build.env
    
    var webpackConfig = merge(baseWebpackConfig, {
      module: {
        rules: utils.styleLoaders({
          sourceMap: config.build.productionSourceMap,
          extract: true
        })
      },
      devtool: config.build.productionSourceMap ? '#source-map' : false,
      output: {
        path: config.build.assetsRoot,
        filename: utils.assetsPath('js/[name].[chunkhash].js'),
        chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
      },
      plugins: [
        // http://vuejs.github.io/vue-loader/en/workflow/production.html
        new webpack.DefinePlugin({
          'process.env': env
        }),
        new webpack.optimize.UglifyJsPlugin({
          compress: {
            warnings: false
          },
          sourceMap: true
        }),
        // extract css into its own file
        new ExtractTextPlugin({
          filename: utils.assetsPath('css/[name].[contenthash].css')
        }),
        // Compress extracted CSS. We are using this plugin so that possible
        // duplicated CSS from different components can be deduped.
        new OptimizeCSSPlugin({
          cssProcessorOptions: {
            safe: true
          }
        }),
        // generate dist index.html with correct asset hash for caching.
        // you can customize output by editing /index.html
        // see https://github.com/ampedandwired/html-webpack-plugin
    
        /* 注释这个区域的内容 ---------------------- 开始 */
        // new HtmlWebpackPlugin({
        //  filename: config.build.index,
        //  template: 'index.html',
        //  inject: true,
        //  minify: {
        //   removeComments: true,
        //   collapseWhitespace: true,
        //   removeAttributeQuotes: true
        //   // more options:
        //   // https://github.com/kangax/html-minifier#options-quick-reference
        //  },
        //  // necessary to consistently work with multiple chunks via CommonsChunkPlugin
        //  chunksSortMode: 'dependency'
        // }),
        /* 注释这个区域的内容 ---------------------- 结束 */
    
        // split vendor js into its own file
        new webpack.optimize.CommonsChunkPlugin({
          name: 'vendor',
          minChunks: function (module, count) {
            // any required modules inside node_modules are extracted to vendor
            return (
              module.resource &&
              /\.js$/.test(module.resource) &&
              module.resource.indexOf(
                path.join(__dirname, '../node_modules')
              ) === 0
            )
          }
        }),
        // extract webpack runtime and module manifest to its own file in order to
        // prevent vendor hash from being updated whenever app bundle is updated
        new webpack.optimize.CommonsChunkPlugin({
          name: 'manifest',
          chunks: ['vendor']
        }),
        // copy custom static assets
        new CopyWebpackPlugin([{
          from: path.resolve(__dirname, '../static'),
          to: config.build.assetsSubDirectory,
          ignore: ['.*']
        }])
        /* 该位置添加 .concat(utils.htmlPlugin()) ------------------- */
      ].concat(utils.htmlPlugin())
    })
    
    if (config.build.productionGzip) {
      var CompressionWebpackPlugin = require('compression-webpack-plugin')
    
      webpackConfig.plugins.push(
        new CompressionWebpackPlugin({
          asset: '[path].gz[query]',
          algorithm: 'gzip',
          test: new RegExp(
            '\\.(' +
            config.build.productionGzipExtensions.join('|') +
            ')$'
          ),
          threshold: 10240,
          minRatio: 0.8
        })
      )
    }
    
    if (config.build.bundleAnalyzerReport) {
      var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
      webpackConfig.plugins.push(new BundleAnalyzerPlugin())
    }
    
    module.exports = webpackConfig
    

    npm run dev / npm run build 运行/打包
    一个简单的多入口项目就初具模型了,可以实现多个项目共用包资源/组件/接口/工具类等,便于项目管控。

    相关文章

      网友评论

          本文标题:vue2.0 cli +webpack 多入口开发 配置教程附详

          本文链接:https://www.haomeiwen.com/subject/kkwboftx.html