zoukankan      html  css  js  c++  java
  • webpack构建Vue工程

    先开始webpack基本构建

     

    创建一个工程目录 vue-structure

    mkdir vue-structure && cd vue-structure

     

    安装webpack

     

    npm i webpack webpack-cli -D

    创建build目录

    mkdir build

    在build目录里, 创建webpack.config.js

    cd build && touch webpack.config.js

    创建入口文件 src/main.js

    mkdir src

    cd src && touch main.js

    main.js

    alert('hello world!')

    配置npm scripts

    // package.json 
      "scripts": {
        "build": "webpack --config build/webpack.config.js --progress --mode production"
      }

     

    配置devServer

     

    npm i webpack-dev-server -D

    配置npm scripts

    "scripts": {
        ...
        "dev": "webpack-dev-server --config build/webpack.config.js --progress --mode development"
      }

    html 插件

    npm i html-webpack-plugin -D

    webpack配置

    // build/webpack.config.js

    const path = require('path')
    const HtmlWebpackPlugin = require('html-webpack-plugin')

    const resolve = dir => path.join(__dirname, '..', dir)

    module.exports = {
      entry: resolve('src/main.js'),
      output: {
        filename: '[name].[hash:5].js',
        path: resolve('dist')
      },
      devServer: {
        host: '0.0.0.0',
        port: 7000,
        open: true
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: resolve('index.html')
        })
      ]
    }

    运行webpack dev server

    npm run dev

    浏览器自动打开 http://0.0.0.0:7000/

    到这里webpack开发服务基本跑通了。

    配置babel v7

     

    webpack 4.x | babel-loader 8.x | babel 7.x

    npm i -D babel-loader @babel/core @babel/preset-env 

    babel plugin 

    支持动态import()

    npm i @babel/plugin-syntax-dynamic-import -D

    配置webpack.config.js

    module: {
        rules: [
          {
            test: /.js$/,
            use: 'babel-loader',
            exclude: /node_modules/
          }
        ]
      }

    创建.babelrc文件

    {
      "plugins": [
        "@babel/plugin-syntax-dynamic-import"
      ],
      "presets": [
        [
          "@babel/preset-env",
          {
            "modules": false
          }
        ]
      ]
    }

    测试下ES6代码

    test.js

     // src/test.js
      export default () => alert('hello vue!')

    index.html

    // src/index.html
      <body>
        <div id="app">请说say</div>
      </body>

    main.js

    // src/main.js
     document.querySelector('#app').addEventListener('click', () => {
      import('./test.js').then(res => {
        res.default()
      })
    })

    运行下dev

    npm run dev

    点击页面div

    ok 没问题。

    配置Vue Loader

    Vue Loader 是什么?

     

    Vue Loader 是一个 webpack 的 loader,它允许你以一种以单文件组件(*.vue文件) 的格式撰写 Vue 组件

    创建App.vue根组件

    <template>
      <div class="example">{{ msg }}</div>
    </template>

    <script>
    export default {
      data () {
        return {
          msg: 'Hello Vue!'
        }
      }
    }
    </script>

    <style>
    .example {
      color: red;
    }
    </style>

    安装Vue

    npm i vue

    src/main.js

    import Vue from 'vue'
    import App from './App.vue'

    new Vue({
      render: h => h(App)
    }).$mount('#app')

    修改index.html

    <body>
      <div id="app"></div>
    </body>

    运行dev

    npm run dev

    结果报错了 。

    webpack默认只能识别JavaScript文件,不能解析.vue文件(vue单文件组件 是Vue独有的),于是作者提供了vue-loader。

    Vue单文件组件

    https://cn.vuejs.org/v2/guide/single-file-components.html

    配置vue-loader

    npm i vue-loader vue-template-compiler

    vue-template-compiler (peer dependency) 是vue-loader的同版本依赖

    webpack.config.js

    // webpack.config.js
    const VueLoaderPlugin = require('vue-loader/lib/plugin')

    module.exports = {
      module: {
        rules: [
          // ... 其它规则
          {
            test: /.vue$/,
            loader: 'vue-loader'
          }
        ]
      },
      plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin()
      ]
    }

    vue单文件组件中css 也需要css-loader解析

    npm i css-loader -D

    配置webpack

    // webpack.config.js
    const VueLoaderPlugin = require('vue-loader/lib/plugin')

    module.exports = {
      mode: 'development',
      module: {
        rules: [
          {
            test: /.vue$/,
            loader: 'vue-loader'
          },
          // 它会应用到普通的 `.js` 文件
          // 以及 `.vue` 文件中的 `<script>` 块
          {
            test: /.js$/,
            loader: 'babel-loader'
          },
          // 它会应用到普通的 `.css` 文件
          // 以及 `.vue` 文件中的 `<style>` 块
          {
            test: /.css$/,
            use: [
              'vue-style-loader',
              'css-loader'
            ]
          }
        ]
      },
      plugins: [
        // 请确保引入这个插件来施展魔法
        new VueLoaderPlugin()
      ]
    }

    此时运行npm run dev OK了,App.vue被成功挂载到页面

    css预处理器配置

    npm i stylus stylus-loader

    webpack.config.js

    module: {
        rules: [
          {
            test: /.styl(us)?$/,
            use: [
              'vue-style-loader',
              'css-loader',
              'stylus-loader'
            ]
          }
        ]
      }

    vue组件中使用

    <style lang='stylus' scoped>
    .example
      .title
        color: red
    </style>

    postcss配置

    postcss 
    提供了一个解析器,它能够将 CSS 解析成抽象语法树(AST)。

    npm i -D postcss-loader

    autoprefixer(插件) 
    它可以解析CSS文件并且添加浏览器前缀到CSS内容里

    npm i -D autoprefixer

    创建postcss.config.js

    module.exports = {
      plugins: [
        require('autoprefixer')
      ]
    }

    配置webpack

    // webpack.config.js
      module: {
        rules: [
          ...
          {
            test: /.css$/,
            use: [
              devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
              {
                loader: 'css-loader',
                options: {
                  sourceMap: true
                }
              },
              {
                loader: 'postcss-loader',
                options: {
                  sourceMap: true
                }
              }
            ]
          },
          {
            test: /.styl(us)?$/,
            use: [
              devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
              {
                loader: 'css-loader',
                options: {
                  sourceMap: true
                }
              },
              {
                loader: 'postcss-loader',
                options: {
                  sourceMap: true
                }
              },
              {
                loader: 'stylus-loader',
                options: {
                  sourceMap: true
                }
              }
            ]
          }
        ]
      }

    给App.vue添加css3样式

    此时 npm run dev 可以看到 自动添加了浏览器前缀

     

    图片资源加载配置

     

    url-loader

    将图片资源转换成base64 URI

    // webpack.config.js

    module: {
      rules: [
        {
          test: /.(png|svg|jpe?g)$/,
          loader: 'url-loader',
          options: {
            limit: 8192
          }
        }
      ]
    }

    转换后图片地址变为了base64 URI

    file-loader

    加载图标字体

    module: {
      rules: [
        {
          test: /.(woff|woff2|eot|ttf|otf)$/,
          use: ['file-loader']
        }
      ]
    }

     

    cross-env

    设置命令运行时的环境变量 以便在webpack配置文件中区分环境

    npm i cross-env -D

    package.json

     "scripts": {
        "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js --progress --mode production",
        "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.js --progress --mode development"
      },

    css提取

    webpack4

    npm i mini-css-extract-plugin -D

    webpack.config.js

    // 区分当前环境是 development 还是 production
    const devMode = process.env.NODE_ENV === 'development'

    module: {
      rules: [
        {
          test: /.css$/,
          use: [
            devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
            'css-loader'
          ]
        },
        {
          test: /.styl(us)?$/,
          use: [
            devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
            'css-loader',
            'stylus-loader'
          ]
        }
      ]
    },

    plugins: [
      ...
      new MiniCssExtractPlugin({
        filename: '[name].css',
        chunkFilename: '[id].css'
      })
    ]

    开发环境下一般不开启css提取,要不然每次代码改动重新编译速度会慢。通常在生成环境下打包时 才开启css提取。

    此时npm run build, css被单独打包成一个css文件

     

    清理dist目录

     

    生产环境下 为什么要清理dist目录 因为我们的输出文件为了缓存再文件名拼接上hash值,只要文件有改动就会产生新的hash值,dist目录下每次都会新增一份输出文件 但我们只要编译后的最终的那个就可以了

    npm run build 三次 dist目录如下:

    dist
    ├── app.bundle.0e380cea371d050137cd.js
    ├── app.bundle.259c34c1603489ef3572.js
    ├── app.bundle.e56abf8d6e5742c78c4b.js
    ├── index.html
    └── style.css
    module.exports = {
        output: {
        filename: '[name].[hash:6].js',
        path: resolve('dist')
      },
    }

     

    利用webpack插件清理

    clean-webpack-plugin

    npm i clean-webpack-plugin -D

    webpack配置

    // build/webpack.config.js

    const CleanWebpackPlugin = require('clean-webpack-plugin')

    module.exports = {
      plugins: [
        new CleanWebpackPlugin(['dist'], {
          root: path.join(__dirname, '../')
        })
      ]
    }

    然后运行npm run build 每次打包前就会把之前的dist目录清理下

    第二种方式 用rimraf命令 清理dist目录

     

    rimraf

    The UNIX command rm -rf for node.

    npm i rimraf -D

    修改package.json

    "scripts": {
        "clean": "rimraf dist",
        "build": "npm run clean && cross-env NODE_ENV=production webpack --config build/webpack.config.js --progress --mode production",
    }

    npm run build 也是ok的

    .editorconfig

     

    在不同的编辑器和IDEs中为多个从事同一项目的开发人员保持一致的编码风格。

    root = true

    [*]
    charset = utf-8
    end_of_line = lf
    indent_size = 2
    indent_style = space
    insert_final_newline = true
    trim_trailing_whitespace = true

    https://editorconfig.org/

    代码校验 (Linting)

     

    安装eslint

    npm i eslint eslint-plugin-vue -D

    eslint各种安装

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

    创建.eslintrc文件

    {
      root: true,
      env: {
        node: true
      },
      parserOptions: {
        parser: "babel-eslint",
        sourceMap: "module"
      },
      extends: [
        "plugin:vue/essential",
        "standard"
      ],
      rules: {}
    }

     

    webpack中配置eslint

    通过webpack实时编译,进行代码效验

    npm i eslint-loader -D

    webpack.config.js

    module: {
      rules: [
        {
          {
            enforce: 'pre',
            test: /.(js|vue)$/,
            loader: 'eslint-loader',
            exclude: /node_modules/
          },
          ......
        }
      ]
    }

    在src/main.js中定义一个未使用变量

    let title = 'eslint'

    运行 npm run dev

    eslint基本配置完了 但是我想在控制台报错信息更友好些.

    eslint-friendly-formatter

     

    一个简单的eslint格式设置工具/报告器,它使用高级文本和iterm2“点击打开文件”功能友好

    安装

    npm i -D eslint-friendly-formatter

    修改webpack配置

    // build/webpack.config.js

    module: {
      rules: [
        {
          {
            enforce: 'pre',
            test: /.(js|vue)$/,
            loader: 'eslint-loader',
            exclude: /node_modules/,
            options: {
              formatter: require('eslint-friendly-formatter')
            }
          },
          ......
        }
      ]
    }

    再次 npm run dev

    此时命令行中报错信息更加友好 显示rules详细规则

    devServer.overlay

     

    把编译错误,直接显示到浏览器页面上。

    webpack.config.js

    module.exports = {
      devServer: {
        overlay: {
          errors: true,
          warnings: true
        }
      }
    }

    再次npm run dev 这样就可以直接在页面中看到错误信息了 

    package.json中配置eslint

    "scripts": {
        "lint": "eslint --ext .js,.vue src"
      },

    通过npm 单独进行效验代码也可以

    npm run lint

    eslint自动修复

    Eslint检测出的问题如何自动修复

    "scripts": {
        "lint": "eslint --ext .js,.vue src",
        "lint:fix": "eslint --fix --ext .js,.vue src"
      },
    npm run lint:fix

    会把你代码中一些常规错误 进行自动修复

    Git Hooks

     

    Git 能在特定的重要动作发生时触发自定义脚本。 

    类似于框架中的生命周期

    husky

     

    npm install husky --save-dev

    创建.huskyrc

    // .huskyrc
    {
      "hooks": {
        "pre-commit": "npm run lint"
      }
    }

    package.json

     "scripts": {
        "lint": "eslint --ext .js,.vue src"
      },

    当每次git commit时 自动执行npm run lint效验

     

    webpack代码分离

     

    代码分离 属于性能优化 (业务代码 第三方代码 webpack运行时生成代码…)

    webpack4中直接配置就可以

    // build/webpack.config.js

    module.exports = {
        optimization: {
        splitChunks: {
          // 默认将node_modules中依赖打包到venders.js
          chunks: 'all'
        },
        // 将webpack运行时生成代码打包到runtime.js
        runtimeChunk: true
      },
    }

    此时 npm run build 会看到vendors.js 和 runtime.js

    webpack4中 optimization选项更多配置请看官方文档

    https://webpack.js.org/configuration/optimization/

    目前完整配置文件

    package.json

     "scripts": {
        "clean": "rimraf dist",
        "build": "npm run clean && cross-env NODE_ENV=production webpack --config build/webpack.config.js --progress --mode production",
        "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.js --progress --mode development",
        "lint": "eslint --ext .js,.vue src",
        "lint:fix": "eslint --fix --ext .js,.vue src"
      },

    build/webpack.config.js

    const path = require('path')
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    const CleanWebpackPlugin = require('clean-webpack-plugin')

    const resolve = dir => path.join(__dirname, '..', dir)

    const devMode = process.env.NODE_ENV === 'development'

    module.exports = {
      entry: resolve('src/main.js'),
      output: {
        filename: '[name].[hash:6].js',
        path: resolve('dist')
      },
      module: {
        rules: [
          {
            enforce: 'pre',
            test: /.(js|vue)$/,
            loader: 'eslint-loader',
            exclude: /node_modules/,
            options: {
              formatter: require('eslint-friendly-formatter')
            }
          },
          {
            test: /.vue$/,
            use: 'vue-loader',
            exclude: /node_modules/
          },
          {
            test: /.js$/,
            use: 'babel-loader',
            exclude: /node_modules/
          },
          {
            test: /.css$/,
            use: [
              devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
              {
                loader: 'css-loader',
                options: {
                  sourceMap: true
                }
              },
              {
                loader: 'postcss-loader',
                options: {
                  sourceMap: true
                }
              }
            ]
          },
          {
            test: /.styl(us)?$/,
            use: [
              devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
              {
                loader: 'css-loader',
                options: {
                  sourceMap: true
                }
              },
              {
                loader: 'postcss-loader',
                options: {
                  sourceMap: true
                }
              },
              {
                loader: 'stylus-loader',
                options: {
                  sourceMap: true
                }
              }
            ]
          },
          {
            test: /.(png|svg|jpe?g)$/,
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/,
            use: ['file-loader']
          }
        ]
      },
      optimization: {
        splitChunks: {
          // 默认将node_modules中依赖打包到venders.js
          chunks: 'all'
        },
        // 将webpack运行时代码打包到runtime.js
        runtimeChunk: true
      },
      devServer: {
        host: '0.0.0.0',
        port: 7000,
        open: true,
        overlay: {
          warnings: true,
          errors: true
        }
      },
      plugins: [
        new VueLoaderPlugin(),
        new MiniCssExtractPlugin({
          filename: '[name].css',
          chunkFilename: '[id].css'
        }),
        new HtmlWebpackPlugin({
          template: resolve('index.html')
        })
        // new CleanWebpackPlugin(['dist'], {
        //   root: path.join(__dirname, '../')
        // })
      ]
    }
  • 相关阅读:
    可爱的中国电信 请问我们的电脑还属于我们自己吗?
    了解客户的需求,写出的代码或许才是最优秀的............
    DELPHI DATASNAP 入门操作(3)简单的主从表的简单更新【含简单事务处理】
    用数组公式获取字符在字符串中最后出现的位置
    在ehlib的DBGridEh控件中使用过滤功能(可以不用 MemTableEh 控件 适用ehlib 5.2 ehlib 5.3)
    格式化json返回的时间
    ExtJs中使用Ajax赋值给全局变量异常解决方案
    java compiler level does not match the version of the installed java project facet (转)
    收集的资料(六)ASP.NET编程中的十大技巧
    收集的资料共享出来(五)Asp.Net 权限解决办法
  • 原文地址:https://www.cnblogs.com/wuxianqiang/p/10580246.html
Copyright © 2011-2022 走看看