资讯专栏INFORMATION COLUMN

vue-cli#4.7项目结构分析

EastWoodYang / 1160人阅读

摘要:前言使用过进行项目开发的同学,一定知道或者使用过脚手架,他能够很好的搭建项目结构和工程,让我们能够把足够的精力放在业务开发上。对象提供一系列属性,用于返回系统信息返回当前进程的命令行参数数组。

前言

使用过 vue 进行项目开发的同学,一定知道或者使用过 vue-cli 脚手架,他能够很好的搭建项目结构和工程,让我们能够把足够的精力放在业务开发上。也正是因为这样,很多时候我们会因为项目工期短等原因来不及或则不会刻意去了解项目工程配置,我们今天不去介绍脚手架的使用,我们去了解下脚手架为我们创建好的打包工程是怎么做的。

项目结构

    ├── build --------------------------------- webpack相关配置文件
    │   ├── build.js --------------------------webpack打包配置文件
    │   ├── check-versions.js ------------------------------ 检查npm,nodejs版本
    │   ├── logo.png ---------------------------------- 项目 logo
    │   ├── utils.js --------------------------------------- 配置资源路径,配置css加载器
    │   ├── vue-loader.conf.js ----------------------------- 配置css加载器等
    │   ├── webpack.base.conf.js --------------------------- webpack基本配置
    │   ├── webpack.dev.conf.js ---------------------------- 用于开发的webpack设置
    │   ├── webpack.prod.conf.js --------------------------- 用于打包的webpack设置
    ├── config ---------------------------------- 配置文件
           ├── index.js ------------------------------ 开发和生产环境配置文件
    ├── node_modules ---------------------------- 存放依赖的目录
    ├── src ------------------------------------- 源码
    │   ├── assets ------------------------------ 静态文件
    │   ├── components -------------------------- 组件
    │   ├── main.js ----------------------------- 主js
    │   ├── App.vue ----------------------------- 项目入口组件
    │   ├── router ------------------------------ 路由
    ├── package.json ---------------------------- node配置文件
    ├── .babelrc--------------------------------- babel配置文件
    ├── .editorconfig---------------------------- 编辑器配置
    ├── .gitignore------------------------------- 配置git可忽略的文件

webpack配置划重点
在看项目配置文件之前,我们先了解下 webpack 几个常用的工具和插件,如果你已经十分熟悉,你可以跳过这一小节,直接去看,配置文件解析
1. path模块

path 是 node.js 中的一个模块,用于处理目录的对象,提高开发效

常用方法:
path.join(): 用于连接路径。该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix 系统是 ”/“,Windows系统是 ”“
path.resolve() 用于将相对路径转为绝对路径

常使用的文件路径
__dirname: 总是返回被执行的 js 所在文件夹的绝对路径
__filename: 总是返回被执行的 js 的绝对路径
process.cwd(): 总是返回运行 node 命令时所在的文件夹的绝对路径


2.process

process对象是Node的一个全局对象,提供当前Node进程的信息。

process 对象提供一系列属性,用于返回系统信息
process.argv:返回当前进程的命令行参数数组。
process.env:返回一个对象,成员为当前Shell的环境变量,比如process.env.HOME
process.pid:当前进程的进程号

3.Source map

简单说,Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。有了它,出错的时候,debug 工具将直接显示原始代码,而不是转换后的代码。这无疑给开发者带来了很大方便。webpack 的 devtool里有 7种 SourceMap 模式

模式 解释
eval 每个 module 会封装到 eval 里包裹起来执行,并且会在末尾追加注释 //@ sourceURL
source-map 生成一个 SourceMap 文件.
hidden-source-map 和 source-map 一样,但不会在 bundle 末尾追加注释.
inline-source-map 生成一个 DataUrl 形式的 SourceMap 文件.
eval-source-map 每个 module 会通过 eval() 来执行,并且生成一个 DataUrl 形式的 SourceMap .
cheap-source-map 生成一个没有列信息(column-mappings)的 SourceMaps 文件,不包含 loader 的 sourcemap(譬如 babel 的 sourcemap)
cheap-module-source-map 生成一个没有列信息(column-mappings)的 SourceMaps 文件,同时 loader 的 sourcemap 也被简化为只包含对应行的。
4. webpack-merge

开发环境(development)和生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server。而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。通用的配置部分,我们抽象出一个公共文件,通过 webpack-merge 工具的“通用”配置,我们不必在环境特定的配置中重复代码。

5. ExtractTextWebpackPlugin

ExtractTextWebpackPlugin 插件通常用来做样式文件的分离,被分离的文件不会被内嵌到 JS bundle 中,而会被放到一个多带带的文件中,在样式文件比较大的时候,能够提前样式的加载,配置示例如下

const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
   module: {
      rules: [
      {
         test: /.css$/,
         use: ExtractTextPlugin.extract({
         fallback: "style-loader",
         use: "css-loader"
      })
   }]
},
    plugins: [
        new ExtractTextPlugin("styles.css"),
    ]
}

它会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个多带带的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。

6.html-webpack-plugin

如果你有多个 webpack 入口点, 他们都会在生成的HTML文件中的 script 标签内。如果你有任何 CSS assets 在 webpack 的输出中(例如, 利用ExtractTextPlugin提取CSS), 那么这些将被包含在HTML head中的标签内。通常在开发中,我们为了避免 CDN 和浏览器的缓存通常会个输出文件 bundle.js 加上一个hash 值例如 [hash].bundle.js,使用 html-webpack-plugin 能够在创建新的 html 文件的时候将我们把带有哈希值的 bundle.js 引用到 html 文件.

7.optimize-css-assets-webpack-plugin

用来优化从脚本里提炼出来的 css ,配置示例如下

var OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
  module: {
    rules: [
      {
        test: /.css$/,
        loader: ExtractTextPlugin.extract("style-loader", "css-loader")
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("styles.css"),
    new OptimizeCssAssetsPlugin({
      assetNameRegExp: /.optimize.css$/g,
      cssProcessor: require("cssnano"),
      cssProcessorOptions: { discardComments: { removeAll: true } },
      canPrint: true
    })
  ]
};
8.CopyWebpackPlugin

CopyWebpackPlugin从插件名称上我们不难看出他的作用,通常用来拷贝资源,对项目文件进行归类整合

9.friendly-errors-webpack-plugin

friendly-errors-webpack-plugin能够更好在终端看到webapck运行的警告和错误,提高开发体验

10.UglifyjsWebpackPlugin

UglifyjsWebpackPlugin用来压缩 js 代码

11.开发中 Server(DevServer)

webpack 项目服务,我们通常会在开发阶段用来配置项目的热刷新,服务压缩,项目代理等,常用的几个配置参数介绍如下

const config = require("../config")

// config 文件里做了用户自定的服务参数配置

devServer: {
    clientLogLevel: "warning",  // 在开发攻击的控制台中显示信息,便于开发调试,你可以将参数配置成 "none" 来进行关闭
     historyApiFallback: { // 当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html
        rewrites: [
           { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, "index.html") },
        ],
     },
     hot: true,   //启用项目的热刷新,即模块热替换特性
     contentBase: false,   // 告诉服务器从哪里提供内容。只有在你想要提供静态文件时才需要。这里禁用,因为配置了 CopyWebpackPlugin 的使用
     compress: true,
     host: HOST || config.dev.host,   //指定使用一个域名。默认是 localhost
     port: PORT || config.dev.port,   //指定要监听请求的端口号:
     open: config.dev.autoOpenBrowser, //open 参数配置,如果配置成 true ,项目启动后会自动打开浏览器
     overlay: config.dev.errorOverlay   //当有错误或则警告的时候在页面上显示一个全屏的遮罩提示
         ? { warnings: false, errors: true }
         : false,
     publicPath: config.dev.assetsPublicPath, //此路径下的打包文件可在浏览器中访问
     proxy: config.dev.proxyTable,           //代理API的请求
     quiet: true,       //启用 quiet 后,除了初始启动信息之外的任何内容都不会被打印到控制台,特别是使用了 FriendlyErrorsPlugin 插件的时候
     watchOptions: {   //与监视文件相关的控制选项。是否使用轮询
           poll: config.dev.poll,
     }
},


配置文件解析
通过了解了上面的配置,我们应该对 webpack 的常用插件和工具有了一定了解,我们来看下 vue-cli 脚手架给我们生成的配置情况
config.js

"use strict"

const path = require("path") // 引用项目的 path 模块

module.exports = {
dev: {

// 路径配置
assetsSubDirectory: "static",
assetsPublicPath: "/",
proxyTable: {},

// 各种开发服务配置
host: "localhost", // 开发环境域名 可以被 node 全局变量process.env.HOST 重写
port: 8080, //配置开发服务端口,可以被 node 全局变量 process.env.PORT 重写, 需要使用未被占用的端口
autoOpenBrowser: false, //服务启动是否自动代开浏览器
errorOverlay: true,   //是否在发生错误的时候,在页面整屏增加一个错误遮罩
notifyOnErrors: true,  //是否通知错误 ,在我们的项目配置中和 friendly-errors-webpack-plugin 结合使用
poll: false, // 服务监听是否轮询操作

// 配饰是否使用 Eslint Loader 进行语法检测
// 如果使用,在开发构建阶段,会对你的代码会进行检测
// 检测出来的警告和错误会白展示在开发工具的控制台

useEslint: true,  //进行语法检测

// 配置是否将 eslint 语法检测的警告和错误展示在页面整屏的遮罩上

showEslintErrorsInOverlay: false,  // 语法检测的警告和错误不展示在遮罩上

/**
 * Source Maps
 */

// https://webpack.js.org/configuration/devtool/#development
// 在上面的介绍中,我们知道 source map 是用来将我们构建后被转化的代码对应构建前的代码,便于 debug
// cheap-module-eval-source-map 和我们介绍的 cheap-module-source-map 很类似,但是 SourceMap 会被作为数据添加到包中
devtool: "cheap-module-eval-source-map",

// 如果你的开发工具不能进行 vue-files 的 debug ,可以将以下设置设置成 false

cacheBusting: true,

cssSourceMap: true

},

build: {

// index.html 文件模板
index: path.resolve(__dirname, "../dist/index.html"),

// 打包路径配置
assetsRoot: path.resolve(__dirname, "../dist"),
assetsSubDirectory: "static",
assetsPublicPath: "/",

/**
 * Source Maps
 */

//生产环境 source map 配置

productionSourceMap: true,
devtool: "#source-map",

// 因为很多的主流服务都会 通过 gzip 压缩过你的所有静态资源,我们的配置默认不开启 gzip
// 如果要设置成开启,请先确保已经安装好 compression-webpack-plugin 插件
productionGzip: false,
productionGzipExtensions: ["js", "css"],

// 启动 build 命令的时候,额外添加一个参数,打包后会自动生成一个分析报告文件,例如 npm run build --report ,可以通过配置 true ,false 来关闭
bundleAnalyzerReport: process.env.npm_config_report

}
}

check-versions.js

这个文件主要是用来检测当前环境中的node和npm版本和我们需要的是否一致的。

"use strict"
const chalk = require("chalk")  // 改变命令行中的字体颜色,大致这样用chalk.blue("Hello world")
const semver = require("semver")  //是用来对特定的版本号做判断的

const packageConfig = require("../package.json")  // 项目 npm 配置文件,获取依赖及版本信息,requrie返回的就是json对象
const shell = require("shelljs") //用来执行Unix系统命令,调用系统命令更加方便

//把cmd这个参数传递的值转化成前后没有空格的字符串,也就是版本号
function exec (cmd) {
  return require("child_process").execSync(cmd).toString().trim()
}


const versionRequirements = [
  {
    name: "node",
    currentVersion: semver.clean(process.version),  // 提取进程版本信息转化成规定格式,也就是 "  =v1.2.3  " -> "1.2.3" 这种功能
    versionRequirement: packageConfig.engines.node // package.json 的 node 的版本信息
  }
]

if (shell.which("npm")) {
  versionRequirements.push({
    name: "npm",
    currentVersion: exec("npm --version"),   //当前的版本信息
    versionRequirement: packageConfig.engines.npm //package.json 的 node 的版本信息
  })
}

module.exports = function () {
  const warnings = []

  for (let i = 0; i < versionRequirements.length; i++) {
    const mod = versionRequirements[i]

    // 如果当前版本号不符合 package.json 要求的版本号,红色表示当前版本信息,绿色表示要求的版本信息,添加到 warnings 待输出
    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
      warnings.push(mod.name + ": " +
        chalk.red(mod.currentVersion) + " should be " +
        chalk.green(mod.versionRequirement)
      )
    }
  }

  //输出版本号不相符的提示 warnings
  if (warnings.length) {
    console.log("")
    console.log(chalk.yellow("To use this template, you must update following to modules:"))
    console.log()

    for (let i = 0; i < warnings.length; i++) {
      const warning = warnings[i]
      console.log("  " + warning)
    }

    console.log()
    process.exit(1)
  }
}



build.js
"use strict"

//打包前判断当先开发环境的 node 和 npm 版本和 package.json 要求的时候一样
require("./check-versions")()

process.env.NODE_ENV = "production"

const ora = require("ora")  // 在用户打包的时候能够让用户知道正在进行,一个加载中的样式,转啊转
const rm = require("rimraf") //这个模块是用来清除之前的打的包,因为在vue-cli中每次打包会生成不同的hash
const path = require("path") //node 路径模块,便于我们操作文件路径
const chalk = require("chalk") //带颜色的输出模块,能在控制台中输出不同的样色
const webpack = require("webpack") //webpack 不解释
const config = require("../config") // 项目中的配置文件,           
               
                                           
                       
                 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94904.html

相关文章

  • 一个基于vue的图片轮播组件的实现

    摘要:在线首先是一张思维导图然后是以上属性的标注说明代码层除去可从父组件接收的属性,组件自身有以下属性当前显示的图片列表鼠标是否悬浮在组件上自动切换的每项元素的宽度是否是反向切换,触发时,该属性为组件挂载之前计算每项元素的宽度,即的值初始化显示 1. 在线DEMO http://va-carousel.xiaoshang.online Github 2. 首先是一张思维导图 showImg(...

    DevTalking 评论0 收藏0
  • vue-cli 构建 vue 项目详解

    摘要:打开浏览器输入,会看到构建的项目的主页目录结构使用编辑器打开推荐使用,下面具体看看目录结构在中,根据我们在构建项目的时候的选项,有以下几个命令。 构建一个 vue 项目最简单的方式就是使用脚手架工具 vue-cli 。前端的三大框架都有自己的脚手架工具,其作用就是用配置好的模板迅速搭建起一个项目工程来,省去自己配置 webpack 配置文件的基本内容,大大降低了初学者构建项目的难度。这...

    JeOam 评论0 收藏0
  • vue-cli 项目结构

    摘要:项目结构为我们搭建开发所需要的环境目录结构及主要功能项目构建相关代码生产环境构建代码检查等版本热重载相关构建本地服务器构建工具相关基础配置开发环境配置生产环境配置项目开发环境配置开发环境 Vue-cli 项目结构 vue-cli 为我们搭建开发所需要的环境 目录结构及主要功能 |-- build // 项目构建(webpack)...

    int64 评论0 收藏0
  • vue-cli 项目结构

    摘要:项目结构为我们搭建开发所需要的环境目录结构及主要功能项目构建相关代码生产环境构建代码检查等版本热重载相关构建本地服务器构建工具相关基础配置开发环境配置生产环境配置项目开发环境配置开发环境 Vue-cli 项目结构 vue-cli 为我们搭建开发所需要的环境 目录结构及主要功能 |-- build // 项目构建(webpack)...

    Markxu 评论0 收藏0
  • vue-cli 项目结构

    摘要:项目结构为我们搭建开发所需要的环境目录结构及主要功能项目构建相关代码生产环境构建代码检查等版本热重载相关构建本地服务器构建工具相关基础配置开发环境配置生产环境配置项目开发环境配置开发环境 Vue-cli 项目结构 vue-cli 为我们搭建开发所需要的环境 目录结构及主要功能 |-- build // 项目构建(webpack)...

    trilever 评论0 收藏0

发表评论

0条评论

EastWoodYang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<