zoukankan      html  css  js  c++  java
  • 从0开始搭建vue+webpack脚手架(四)

    之前1-3部分是webpack最基本的配置, 接下来会把项目结构和配置文件重新设计,可以扩充更多的功能模块。

    一、重构webpack的配置项

    1. 新建目录build,存放webpack不同的配置文件

      (1) webpack.config.base.js  【保留公共的配置项,将生产环境和开发环境使用的配置项分离出去】

     1 const path = require('path')
     2 const webpack = require('webpack')
     3 const VueLoaderPlugin = require('vue-loader/lib/plugin')
     4 const HtmlWebpackPlugin = require('html-webpack-plugin')
     5 const CleanWebpackPlugin = require('clean-webpack-plugin')
     6 
     7 const isDev = process.env.NODE_ENV === 'development'
     8 
     9 const config = {
       mode: process.env.NODE_ENV || 'production'
    10 target: 'web', 11 performance: { 12 hints: false, 13 maxAssetSize: 500000 14 }, 15 entry: path.join(__dirname, '../src/index.js'), 16 output: { 17 path: path.join(__dirname, '../dist'), 18 filename: 'scripts/bundle.[hash:8].js' 19 }, 20 module: { 21 rules: [ 22 { 23 test: /.vue$/, 24 use: [ 25 { 26 loader: "vue-loader" 27 } 28 ] 29 }, 30 { 31 test: /.jsx$/, 32 loader: "babel-loader" 33 }, 34 { 35 test: /.js$/, 36 loader: "babel-loader", 37 exclude: /node_modules/ 38 }, 39 { 40 test: /.(jpg|jpeg|gif|png|svg)$/, 41 use: [ 42 { 43 loader: "url-loader", 44 options: { 45 limit: 1024, 46 name: 'images/[name]-[hash:8].[ext]' 47 } 48 } 49 ] 50 } 51 ] 52 }, 53 plugins: [ 54 new VueLoaderPlugin() 55 ] 56 } 57 58 module.exports = config

    注意: 入口文件和输出路径

    注意: VueLoaderPlugin是使用vue-loader必须的,两种环境都需要加载。jsx和js的规则分开配置,因为js编译时需要除去node_modules目录下的文件。

      (2) webpack.config.client.js 【配置开发和生产环境环境需要的选项】

        安装 webpack-merge工具, 提供配置文件扩展方法。

    1 $ npm i -D webpack-merge

        (3)  在webpack.config.client.js中使用merge对基础的配置baseConfig进行扩展。

      1 const path = require('path')
      2 const webpack = require('webpack')
      3 const merge = require('webpack-merge')
      4 const VueLoaderPlugin = require('vue-loader/lib/plugin')
      5 const HtmlWebpackPlugin = require('html-webpack-plugin')
      6 const CleanWebpackPlugin = require('clean-webpack-plugin')
      7 const ExtractTextPlugin = require('extract-text-webpack-plugin')
      8 const baseConfig = require('./webpack.config.base')
      9 
     10 const isDev = process.env.NODE_ENV === 'development'
     11 const basePlugin = [
     12   new VueLoaderPlugin(),
     13   new CleanWebpackPlugin(['../dist']),
     14   // 根据不同环境区分打包
     15   new webpack.DefinePlugin({
     16     'process.env': {
     17       NODE_ENV: isDev ? '"development"' : '"production"',
     18     }
     19   }),
     20   new HtmlWebpackPlugin({
     21     template: path.join(__dirname, '../index.html')
     22   })
     23 ]
     24 const devServer = {
     25   port: 9000,
     26   host: '0.0.0.0',
     27   overlay: {
     28     errors: true
     29   },
     30   historyApiFallback: true,
     31   hot: true,
     32 }
     33 
     34 let config
     35 
     36 if (isDev) {
     37   config = merge(baseConfig, {
     38     // mode: 'development',
     39     // devtool: '#cheap-module-eval-source-map',
     40     module: {
     41       rules: [
     42         {
     43           test: /.css$/,
     44           use: ['style-loader', 'css-loader']
     45         },
     46         {
     47           test: /.styl(us)?$/,
     48           use: [
     49             'style-loader',
     50             'css-loader',
     51             {
     52               loader: "postcss-loader",
     53               options: {
     54                 sourceMap: true
     55               }
     56             },
     57             'stylus-loader',
     58           ]
     59         },
     60       ]
     61     },
     62     devServer,
     63     plugins: basePlugin.concat([
     64       new webpack.HotModuleReplacementPlugin(),
     65       new webpack.SourceMapDevToolPlugin() // devtool
     66     ])
     67   })
     68 } else {
     69   config = merge(baseConfig, {
     70     // mode: 'production',
     71     entry: {
     72       app: path.join(__dirname, '../src/index.js'),
     73       vendor: ['vue']
     74     },
     75     output: {
     76       filename: 'scripts/[name].[chunkhash:8].js'
     77     },
     78     module: {
     79       rules: [
     80         {
     81           test: /.css$/,
     82           use: ExtractTextPlugin.extract({
     83             fallback: 'style-loader',
     84             use: ['css-loader']
     85           })
     86         },
     87         {
     88           test: /.styl(us)?$/,
     89           use: ExtractTextPlugin.extract({
     90             fallback: 'style-loader',
     91             use: [
     92               'css-loader',
     93               {
     94                 loader: "postcss-loader",
     95                 options: {
     96                   sourceMap: true
     97                 }
     98               },
     99               'stylus-loader',
    100             ]
    101           })
    102         },
    103       ]
    104     },
    105     plugins: basePlugin.concat([
    106       new ExtractTextPlugin('style.[hash:8].css'),
    107     ]),
    108     optimization: {
    109       splitChunks: {
    110         chunks: 'all'  // name: 'vendor'
    111       },
    112       runtimeChunk: true 115     }
    116   })
    117 }
    118 
    119 module.exports = config

    注意红色部分的修改:

      1 .引入merge工具 和 webpack.config.base.js

      2 .将公共plugin提取保存在变量 basePlugin, 不在base.js中使用的原因是后续的服务端渲染时无需使用, 故只在生产环境和开发环境引用。

      3. 将devServer提取保存在变量中。

      4. 声明变量config, 保存通过merge以baseConfig为基础扩展的配置项

      5. basePlugin.concat()将公共的plugin添加到不同环境

    修改package.json的运行脚本

    1 "scripts": {
    2     "test": "echo "Error: no test specified" && exit 1",
    3     "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.client.js --colors --progress",
    4     "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js --colors --progress",
    5     "start": "npm run dev"
    6 },

    注意, 指向指定路劲时必须使用 --config否则报错无法编译。之前不用--config是因为默认指向了根目录的webpack.config.js

    至此: 运行 $ npm run build $ npm run dev正常。

    另注: 如果后续需要编写服务端的代码,可以将项目分为client/ 和 server/ 两个目录,分别存放服务端和客户端的业务代码, 如下

    将原来的src/改成client/ 注意别忘了修改 webpack.config.base.js和 webpack.config.client.js内的相关路径。目录修改根据自己的习惯和环境而定。

    二、使用rimraf工具 ,在打包前删除旧包

      1. 之前使用的是clean-webpack-plugin,rimraf也有同样的功能,但rimraf可以直接写在scripts脚本内

      2. 安装 $ npm i -D rimraf

      3 . 添加到 scripts中

    1 "scripts": {
    2     "test": "echo "Error: no test specified" && exit 1",
    3     "build": "npm run clean && cross-env NODE_ENV=production webpack --config build/webpack.config.client.js --colors --progress",
    4     "dev": "npm run clean && cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js --colors --progress",
    5     "start": "npm run clean && npm run dev",
    6     "clean": "rimraf dist"
    7 },

    三、添加eslint代码校验

      (1)安装eslint及其依赖

    npm i -D eslint 
    npm i -D eslint-config-standard eslint-plugin-standard 
    npm i -D eslint-plugin-promise eslint-plugin-import eslint-plugin-node
    npm i -D eslint-plugin-html

      特别要说明的是,在vue项目中,eslint默认是无法解析.vue的文件, 所以需要使用 eslint-plugin-html插件来解析 , 其他都是辅助eslint的插件和工具 

    (2)创建 .eslinrc配置文件

    {
      "extends": "standard",
      "plugins": [
        "html"
      ]
    }

     (3)package.json中添加命令

    1 "scripts": {
    2     "test": "echo "Error: no test specified" && exit 1",
    3     "build": "npm run clean && cross-env NODE_ENV=production webpack --config build/webpack.config.client.js --colors --progress",
    4     "dev": "npm run clean && cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js --colors --progress",
    5     "lint": "eslint --ext .js --ext .jsx --ext .vue client/",
    6     "fix": "eslint --fix --ext .js --ext .jsx --ext .vue client/",
    7     "start": "npm run clean && npm run dev",
    8     "clean": "rimraf dist"
    9 },

    配置完成后运行脚本 : $ npm run lint会提示出一系列的警告。这是因为之前编写的代码中有些不符合eslint的默认规范。 可以使用 $ npm run  fix命令批量修复。

      (4)错误

      在新版本的eslint中,如果设置extends为 'standard'则会报错:(不再支持"standard"的方式, 具体原因暂时未知),将eslinrc修改如下

     1 module.exports = {
     2   "env": {
     3     "browser": true,
     4     "commonjs": true,
     5     "es6": true
     6   },
     7   "extends": ["eslint:recommended"],
     8   "plugins": [
     9     "html"
    10   ]
    11 }

    运行 $ npm run lint 但又出现错误:都不能使用export和 import, 继续添加配置

    1 "parserOptions": {
    2     "ecmaFeatures": {
    3       "jsx": true
    4     },
    5     "ecmaVersion": 2015,
    6     "sourceType": "module"
    7 },

    此时运行 $ npm run lint不再报错。

    以上是使用 eslint-plugin-html 解析vue文件 , 也可以使用插件 eslint-plugin-vue来解析vue 文件,安装插件后修改eslintrc

    1 "extends": ["eslint:recommended", "plugin:vue/essential"],
    2   "plugins": [
    3     "vue"
    4  ],

    运行 $ npm run lint检查错误, 运行 $ npm run fix修正错误。

      (5)在webpack项目中使用eslint-loader

       安装 

    1 $ npm i -D eslint-loader
    2 $ npm i -D babel-eslint

        eslintrc的 parserOptions 中添加 babel-eslint

    1 "parserOptions": {
    2     "parser": "babel-eslint",   // 解析检测babel的代码
    3     "ecmaFeatures": {    
    4       "jsx": true          // 检测jsx语法
    5     },  
    6     "ecmaVersion": 2015,
    7     "sourceType": "module" 
    8  },

        在 webpack.config.base.js中 rules 添加 eslint 规则

    1 {
    2    test: /.(vue|js|jsx)$/,
    3    exclude: /node_modules/,
    4    loader: "eslint-loader",
    5    enforce: "pre"   // 预处理,在匹配的文件编译前先检测语法
    6 },

    至此, 运行项目, 并在业务文件内改成有错误的格式, eslint将会自动检测到后提示错误, 只要再修改回来即可正常。

    接下来在 eslintrc文件中配置 rules,设置指定的语法格式。这里只配置了一小部分,根据项目需求可自定义。

    "rules": {
        "no-new": "off",
        "no-alert": "off",
        "no-console": [
          "off"
        ],
        "eol-last": 0,
        "space-before-function-paren": 0,
        "indent": 0
      }

     0 或者 off一般表示关闭不做解析。如以上代码中"indent" :0表示不做缩进的检测, "indent": 2 表示缩进是两个空格否则会报错, 其他用法可参考官网。

      

  • 相关阅读:
    Bootstrap按钮
    Bootstrap表单
    Bootstrap表格
    Bootstrap列表
    jq 的onchange事件
    php 跳出循环的几种方式
    php变量和字符串连接符——点
    php 从2维数组组合为四维数组分析
    mysql 删除表中记录
    mysql 聚合函数
  • 原文地址:https://www.cnblogs.com/hughes5135/p/9336777.html
Copyright © 2011-2022 走看看