zoukankan      html  css  js  c++  java
  • 019 Vue webpack的使用

    [A] webpack的简介

            1. webpack是一个现代的JavaScript应用的静态模块打包工具

                1. 在开发中,我们可能生成多种格式的文件,如.js, .hbs, .png, sass等等,而最终我们只需要.js, .png, .css文件

                    webpack可以帮助我们实现文件的自动打包和格式转换

                2. 在开发中,模块化开发有很多规范,如CommonJS,AMD, CMD, ES6规范等,但是浏览器只支持ES6规范,缺乏支持其他规范的底层支撑

                    webpack可以提供这种底层支撑,使得开发时可以随意使用各种规范

                3. 在开发中,模块化的开发会使得哥哥模块之间存在错综复杂的依赖,先后顺序处理不好会运行报错

                    webpack可以帮助我们自动化的处理各种依赖关系

                4. 在webpack中,不仅.js被看作模块,图片,CSS,json文件等等都被看作是模块对待

      

      2. webpack的两个核心是:模块和打包

                        模块:

                            1. 在ES6之前,我们要进行模块化开发,就要借助其他工具实现模块化,

                                并且在模块化开发完项目后,还要处理模块之间的依赖关系,将其整合打包

                            2. webpack的一个核心就是进行模块化,并且处理好模块之间的依赖关系

                            3. 在webpack中,js文件,css文件,图片,json文件都可以被视作模块来使用

                        打包:

                            1. 打包就是,webpack将隔俄国模块进行整理打包成一个或者多个包

                            2. 在打包的过程中可以对资源进行处理,

                                比如压缩图片,将scss转化成css,ES6语法转化成ES5语法,Typescript转化成JavaScript等等

            3. webpack与gulp/grunt的对比

                1. gulp/grunt的核心是task

                    首先,我们配置一系列的task,并且定义task要处理的事物(图片压缩,ES6版本转换,scss转成css)

                    然后,让gulp/grunt来自动化的执行这些task,而且整个流程自动化执行

                    因此,gulp/grunt被称为前端自动化任务管理工具

                2. 什么时候用gulp/grunt

                    首先,工程模块依赖关系非常简单,甚至没有模块化的概念

                    其次,只需要进行简单的合并,压缩,使用gulp/grunt即可

                    但是,如果整个项目依赖关系复杂,使用模块化管理,就得考虑webpack了

                3. 区别

                    gulp/grunt更加强调前端流程的自动化,模块不是它的核心

                    webpack更加强调模块化开发管理,而文件合并,图片压缩只是它的附带功能

      4. webpack的运行依赖于node环境.

                        node环境为了能够执行更多的代码,其中包含了一个包管理器cpm(node package manager)

    [B] webpack的安装

      安装webpack(在某个nodejs版本里)

                    1. webpack全局安装

                          控制台指令:

                                 npm install webpack -g

                                  也可以指定webpack版本:

                                 npm install webpack@3.6.0 -g

                    2. webpack本地安装:

                          控制台指令:

                                   npm install webpack --save-dev

                                    也可以指定webpack版本:

                                   npm install webpack@3.6.0 --save-dev

              为什么全局安装之后还要本地安装呢

                            因为在控制台(CMD控制台,console等平台)上运行的webpack命令时调用的是全局webpack

                            但在html,js文档中调用不到全局webpack指令,需本地下载

    [C] webpack 的配置文件

        webpack的配置文件有两个:webpack.config.js和package.json的配置,配置好这两个文件后,我们在控制台直接运行webpack,即可将指定的文件打包并放在指定的位置

      1. 配置webpack.config.js文件

                        1. 指定默认的入口文件名,默认为main.js

                        2. 指定默认的出口文件名, 默认为bundle.js

                        添加package.json文件:

                                1. 在当前目录下,新建一个文件,名为webpack.config.js、

                                2. 在该文件中添加内容如下:

    const path = require("path");
    module.exports = {
        entry: "./src/main.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
            // path是一个模块,resolve方法是将导入的两个路径进行连接
            // __dirname指的是当前文件所在的路径
            filename: "bundle.js"
        }
    }

                   

      2.  配置package.json文件

                            记录node中开发的配置信息

                        1. 在该文件中,可以将webpack指令和npm run 指令对应起来

                                如在package.json文件中的script对象中添加:

                                    build: "webpack",

                                则此后,在控制台输入npm run build,等价于输入webpack

                        2. 在终端和CMD控制台运行的webpack命令都是调用全局的webpack包,

                            而package.json中的script中的指令首先查找本地的webpack包,若没有找到再去全局查找

    [D] webpack中的loader

        loader时webpack中的一个非常核心的概念,loader是一个哦你沟通的概念,并非指某一个文件或者插件

          1. loader能做什么

                   1. webpack可以处理js文件,并且处理js文件之间的依赖关系。

                   2. 到那时开发中,除了处理js文件,还要处理css, 图片,sass和less转为css,

                         ES6转为ES5, TypeScript转化为ES5 .jsx, .vue转化为js文件等等内容

                   3. webpackk本身解决不了这么多问题,但是webpack拓展的loader可以处理这些问题

           2. loader的使用

                    1. 通过npm本地安装loader

                            安装地址:https://www.webpackjs.com/concepts/

                            安装指令:npm install --save-dev loader名

                    2. 在入口文件中导入所需要打包的文件(.css, png,等等一系列文件),使得入口文件依赖于这些文件,方便打包

                            即在main.js文件中添加命令:

                                    require("文件");

                   3. 在webpack.config.js中的modules关键字下进行配置

                                将下载的loader告诉webpack.config.js文件,即在该文件中新增一个module对象。

                                    module对象:

    module: {
        rules: [
            {
                test: /.css$/,
                 use: ["loader名"]
            }
        ]
    }

                  loader的使用示例1: 配置并使用.css打包工具

                            1. 编写一个.css文件,命名为cssStyle.css

                            2. 在webpack的入口文件中导入该css模块,使得入口文件依赖于cssStyle.css文件

                                    具体操作:

                                        在入口文件中加入指令:

                                            require("../css/cssStyle.css");

                            3. 本地下载和安装css打包的工具

                                    下载地址:https://www.webpackjs.com/concepts/

                                    具体操作:

                                        npm install --save-dev css-loader

                                        npm install style-loader --save-dev

                            4. 配置webpack.config.js文件

                                在webpack.config.js文件的module.exports对象中新增一个module对象

                                    module对象:

    module: {
        rules: [
            {
                test: /.css$/,
                use: [
                    { loader: "style-loader" },
                    { loader: "css-loader" }
                ]
            }
        ]
    }

                                【注】style-loader:将模块的导出作为样式添加到 DOM 中

                                      css-loader:   解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码

                                    在use中的读取顺序是从右向左,这两个文件的顺序不能错

                 loader的使用示例2: 配置并使用.less打包工具

                            1. 编写一个.less文件,命名为lessStyle.less

                            2. 在webpack的入口文件中导入该less模块,使得入口文件依赖于lessStyle.less文件

                                    具体操作:

                                        在入口文件中加入指令:

                                            require("../css/lessStyle.less");

                            3. 本地下载和安装css打包的工具

                                    下载地址:https://www.webpackjs.com/concepts/

                                    具体操作:

                                        npm install --save-dev less-loader

                                        npm install --save-dev style-loader

                                        npm install less --save-dev

                            4. 配置webpack.config.js文件

                                在webpack.config.js文件的module.exports对象中的module对象中的rules数组中新增一个数组元素

    {
        test: /.less$/,
        use: ["style-loader", "css-loader", "less-loader"]
    }

                 loader的使用示例3: 配置并使用图片打包工具

                                当css,js文件中有图片时,需要下载打包图片的loader

                            1. 本地下载和安装css打包的工具

                                    下载地址:https://www.webpackjs.com/concepts/

                                    具体操作:

                                        npm install --save-dev url-loader

                            2. 配置webpack.config.js文件

                                在webpack.config.js文件的module.exports对象中的module对象中的rules数组中新增一个数组元素

    {
        test: /.(png|jpg|gif)$/,
        use: [
            {
                loader: 'url-loader',
                options: {
                    // 图片大小限制,单位为B
                    // 当图片实际大小在limit范围内时,只下载url-loader即可,图片会被转化为base64格式的文件
                    // 当图片大小超过limit范围是,还要瞎子啊file-loader,此时图片会以哈希值命名并保存到目标文件夹中
                    // 此时,文件调用会因为路径变了而报错,因此须在本配置文件的output对象中添加元素:publicPath: "dist/"
                    limit: 1500,
                    // 这里的name值是对打包的图片的路径和名字做限制的
                    name: "img/[name].[hash:8].[ext]"
                }
            }
        ]
    }

                  loader的使用示例4: ES6转化成ES5的babel

                                ES6中的一些语法在ES5中不支持,为了更大限度的兼容,有时候需将ES6转化成ES5

                            1. 本地下载和安装css打包的工具

                                    下载地址:https://www.webpackjs.com/concepts/

                                    具体操作:

                                        npm install babel-loader babel-core babel-preset-es2015

                                    【注】版本要对的上使用时才不会报错

                                    检查:

                                        "babel-loader": "^7.1.5",

                                        "babel-core": "^6.26.3",

                                        "babel-preset-es2015": "^6.24.1",

                            2. 配置webpack.config.js文件

                                在webpack.config.js文件的module.exports对象中的module对象中的rules数组中新增一个数组元素

    {
        test: /.js$/,
        // exclude排除,即在node_modules|bower_components这两个文件夹中的js不参与打包
         exclude: /(node_modules|bower_components)/,
        use: {
            loader: 'babel-loader',
            options: {
                presets: ['es2015']
            }
        }
    }

    [E] plugin的使用

      1. plugin使插件的意思,通常指用于对现有的架构进行拓展

      2. webpack中的插件,及时对webpack中现有功能的拓展,比如打包优化,文件压缩等等

      3. loader与plugin的区别

        1. loader主要用于转换某些文件的模块,他是一个转换器

        2. plugin是插件,是对webpack本身的扩展,是一个扩展器

      4. plugin的使用

        1. 通过npm安装需要的plugins(某些wbpack内置的插件不需要安装)

        2. 在webpack.config.js中的plugins中配置插件

      

      plugin使用案例:

                        1. 添加版权说明 BannerPlugin插件

                              1. BannerPlugin插件是webpack自带的一个插件,在webpack.config.js中直接导入webpack包即可

                                  const webpack = require("webpack");

                              2. 在webpack.config.js文件中的module.exports内添加plugins元素:

                                  plugins:[

                                      new webpack.BannerPlugin("最终版权归Carrey所有")

                                  ]

                       

                        2. 打包html文件的插件:HtmlWebpackPlugin插件

                              1. 安装HtmlWebpackPlugin插件

                                  npm install html-webpack-plugin --save-dev

                              2. 在webpack.config.js文件中的plugins中添加配置信息

                                  const HtmlWebpackPlugin = require("html-webpack-plugin");

                                  new HtmlWebpackPlugin({

                                      template:'index.html'

                                      // 以这个文件为模板生成html文件

                                  })

                           

                        3. 压缩js文件的插件:uglifyjs插件

                              1. 安装uglifyjs插件

                                  npm install uglifyjs-webpack-plugin --save-dev

                              2. 在webpack.config.js文件中的plugins中添加配置信息

                                  const uglifyjsPlugin = require("uglifyjs-webpack-plugin");

                                  new uglifyjsPlugin()

    [F] webpack中配置vue

           如果在项目中需要使用vue,则需要先安装,由于开发完之后依然依赖vue,因此vue是运行时依赖

      1. 安装vue:npm run vue --save

      2. 安装vue的三种方式:

                        1. 直接下载vue.js引用

                        2. CND引入

                        3. npm安装vue模块

      3. 引入vue实例

                        1. 在main.js中引入vue模块,并创建vue实例

    import Vue from 'vue'
    const app = new Vue({
        el: "#app",
        data: {
            msg: 'hello Carrey'
        }
    })    

                        2. 将创建的这个app实例添加到index.html文件中

    <body>
        <div id="app">
            <h2>{{msg}}</h2>
        </div>
    </body>

      
      4. 在上述3中会出现引用失败或无效的情况

                        原因:

                                vue在发布的时候有两个版本,分别是runtime-only和runtime-compiler

                            1. runtime-only 该版本不允许代码中有任何的template,因为无法编译

                            2. runtime-compiler 该版本允许代码中有template,因为有专门的模块进行解析

                            3. 而我们在main.js中通过 el: "#app" 方式引入的就是在index.html中定义的template模板

                        解决:

                            1. 在webpack.config.js中进行相关配置,如下:

                                输出元素中添加resolve元素

    module.exports = {
        resolve: {
            // alias: 别名
            alias: {
                'vue$': 'vue/dist/vue.esm.js'
            }
        }
    }

                        解决原理:

                            1. 引用vue模块式默认引用的是vue发布的runtime-only版本,但是该版本不能编译template模板

                            2. 通过webpack.config.js中的配置(如上配置),就可以指定引用的vue文件为vue.esm.js,

                                这是一个runtime-compiler版本,就可以编译template模板了

      5. vue实例中,el与template的区别

                            在上述3引入vue实例时,我们是将模板内容写在index.html中

                            即:

    <body>
        <div id="app">
            <h2>{{msg}}</h2>
        </div>
    </body>    

                            而实际开发中,我们不把模板内容写在index.html文件中,而是写在main.js中创建的实例中

                            即:

    import Vue from 'vue'
    const app = new Vue({
        el: "#app",
        template: `
            <div id="app">
                <h2>{{msg}}</h2>
            </div>
        `
        data: {
             msg: 'hello Carrey'
        }
    }

                            此时index.html文件中只保留引入实例的div

                            即:

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

                        那么el和template到底什么关系呢 ?

                                实际上我们在实际开发中,不希望频繁修改index.html中的内容,

                                但是我们又需要频繁修改index.html中显示的内容(即index.html中的模板内容),怎么办呢

                            使用el时,我们在vue实例中通过el属性与index.html中的#app绑定,之后vue实例就可以管理其中的内容了

                            而当同时定义了el属性和template属性时,template中定义的模板会替换掉el绑定的那个组件的内容

      6. 组件模板的抽离及vue的终极使用方案

                        在上述5中的使用方案中,我们可以进一步将组件抽离,以简化Vue实例

                            1. 在Vue实例中,我们可以将模板,数据以及方法全都抽出来

                            2. 将抽离出来的内容组合成一个组件,写在.vue文件中

                            3. 在vue实例中将这个.vue文件当作一个子组件,在Vue实例中引入并注册。

                        解决.vue文件通过webpack打包报错的问题:

                            1. 这是因为.vue文件,webpack并不认识,无法加载

                            2. 通过配置对应的loader帮助加载

                                npm install vue-loader vue-template-compiler --save-dev

                            3. 在webpack.config.js中进行相关配置

    module:{
        rules: [
            {
                test: /.vue$/,
                use: ['vue-loader']
            }
        ]
    },

                            4. 若此时通过npm run build 打包文件报错,需要如下操作:

                                    遇到报错注意查看报错信息

                                1. 在webpack.config.js中需要安装配套的plugin

    // webpack.config.js
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    module.exports = {
        // ...
        plugins: [
            new VueLoaderPlugin()
        ]
    }

     [G] webpack搭建本地服务器 webpack-dev-server插件

         在开发过程中,一旦修改保存代码,我们就希望看到运行结果,但是每次都需要webpack打包,然后手动运行,这样过于繁琐

        因此我们可以搭建本地服务器,代码发生变动后,自动编译执行并展示在浏览器上

      1.  webpack-dev-server简介

        这是webpack提供的一个可选的本地开发服务器,这个本地服务器是给予nodejs搭建的,内部使用express框架,可以实现想要的让浏览器自动刷新显示我们修改后的结果

      2. 安装 webpack-dev-server

        终端运行:npm install  webpack-dev-server --save-dev

        这个服务器只在开发时便于观察所写代码的运行结果,运行时不需要,因此为开发时依赖。

           3. 在webpack.config.js文件中的module.exports中新增添加配置信息

                        devServer:{

                            contentBase: "./dist",

                            inline: true

                        }

     

      4. 使用本地webpack-dev-server插件启动这个服务器

        在package.json中配置script指令,使用本地包启动服务器

        "dev": "webpack-dev-server"

     

      5. 当使用npm run webpack-dev-server运行这个服务器时,就会启动一个服务器

        当我们需要这个服务器自动打开浏览器网页时,可以将第3步中的指令改为:"dev": "webpack-dev-server --open"

    [H] 配置文件的抽离

        webpack.config.js中的配置文件显的有写冗杂,开发时我们需要将该配置文件进行分离 。 

        将基本的配置信息单独写在一个文件中,将仅在开发时依赖的配置信息单独写在一个配置文件中,将仅在运行时依赖的配置信息单独写在一个配置文件中。

      1. 我们将配置文件webpack.config.js拆分成三个文件:基本配置 base.config.js文件,开发时依赖配置 dev.config.js文件 和 运行时依赖配置 prod.config.js文件。

      2. 原webpack.config.js文件中,存在的属性:

        1. entry:入口文件路径

        2. output:目标文件路径

        3. module:loader配置信息

        4. resolve:解决模块请求时的问题

        5. plugins:配置插件

        6. devServer:搭建本地服务器

    const path = require("path");
    const webpack = require("webpack");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const uglifyjsPlugin = require("uglifyjs-webpack-plugin");
    
    module.exports = {
        entry: "./src/js/main.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
            // path是一个模块,resolve方法是将导入的两个路径进行连接
            // __dirname指的是当前文件所在的路径
            filename: "bundle.js",
            
            // 保存图片的地址
            // publicPath: "dist/"
        },
        module: {
            rules: [
                {
                  test: /.css$/,
                  use: ["style-loader","css-loader" ]
                },
                {
                    test: /.less$/,
                    use: ["style-loader", "css-loader", "less-loader"]
                },
                {
                    test: /.(png|jpg|gif)$/,
                    use: [
                      {
                        loader: 'url-loader',
                        options: {
                            // 图片大小限制,单位为B
                          limit: 1500,
                          name: "img/[name].[hash:8].[ext]"
                        }
                      }
                    ]
                },
                {
                  test: /.js$/,
                  // exclude排除,即在node_modules|bower_components这两个文件夹中的js不参与打包
                  exclude: /(node_modules|bower_components)/,
                  use: {
                    loader: 'babel-loader',
                    options: {
                      presets: ['es2015']
                    }
                  }
                },
                {
                  test: /.vue$/,
                  use: ["vue-loader"]
                }
            ]
        },
        resolve:{
          // alias 别名
          alias:{
            "vue$": "vue/dist/vue.esm.js"
          }
        },
        plugins:[
          new webpack.BannerPlugin("最终版权归Carrey所有"),
          new HtmlWebpackPlugin({
            template:'index.html'
          }),
          new uglifyjsPlugin(),
        ],
        devServer: {
          contentBase: "./dist",
          inline: true
        }
    }
    View Code

      3. 基本配置文件 base.config.js文件

        1. entry:入口文件路径

        2. output:目标文件路径

        3. module:loader配置信息

        4. resolve:解决模块请求时的问题

    const path = require("path");
    const webpack = require("webpack");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const uglifyjsPlugin = require("uglifyjs-webpack-plugin");
    
    module.exports = {
        entry: "./src/js/main.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
            // path是一个模块,resolve方法是将导入的两个路径进行连接
            // __dirname指的是当前文件所在的路径
            filename: "bundle.js",
            
            // 保存图片的地址
            // publicPath: "dist/"
        },
        module: {
            rules: [
                {
                  test: /.css$/,
                  use: ["style-loader","css-loader" ]
                },
                {
                    test: /.less$/,
                    use: ["style-loader", "css-loader", "less-loader"]
                },
                {
                    test: /.(png|jpg|gif)$/,
                    use: [
                      {
                        loader: 'url-loader',
                        options: {
                            // 图片大小限制,单位为B
                          limit: 1500,
                          name: "img/[name].[hash:8].[ext]"
                        }
                      }
                    ]
                },
                {
                  test: /.js$/,
                  // exclude排除,即在node_modules|bower_components这两个文件夹中的js不参与打包
                  exclude: /(node_modules|bower_components)/,
                  use: {
                    loader: 'babel-loader',
                    options: {
                      presets: ['es2015']
                    }
                  }
                },
                {
                  test: /.vue$/,
                  use: ["vue-loader"]
                }
            ]
        },
        resolve:{
          // alias 别名
          alias:{
            "vue$": "vue/dist/vue.esm.js"
          }
        },
    }
    View Code

      4. 开发时依赖的配置文件 dev.config.js 文件

        6. devServer:搭建本地服务器

    // dev.config.js
    module.exports = {
        devServer: {
          contentBase: "./dist",
          inline: true
        }
    }
    View Code

      5. 运行时依赖的配置文件 prod.config.js文件

        5. plugins:配置插件

    // prod.config.js
    const uglifyjsPlugin = require("uglifyjs-webpack-plugin");
    
    module.exports = {
        plugins:[
          new webpack.BannerPlugin("最终版权归Carrey所有"),
          new HtmlWebpackPlugin({
            template:'index.html'
          }),
          new uglifyjsPlugin(),
        ],
    }
    View Code

      6. 文件的合并

          配置文的分离是为了便于开发,但分离的配置文件最终还是要合并的

        1. 安装webpack-merge包,用于合并文件

          终端运行:npm install webpack-merge --save-dev

          开发时依赖,运行时不需要

        2.dev.config.js文件的合并,在配置文件中调用webpack-merge包,对文件进行合并

    // dev.config.js
    // 导入webpack-merge包,用于合并文件
    const webpackMerge = require('webpack-merge')
    // 导入基本配置文件,并将其和本文件进行合并后导出
    const baseConfig = require('./base.config.js')
    
    module.exports = webpackMerge(baseConfig,{
        devServer: {
          contentBase: "./dist",
          inline: true
        }
    })
    View Code

        3. prod.config.js文件的合并,在配置文件中调用webpack-merge包,对文件进行合并

    // prod.config.js
    const uglifyjsPlugin = require("uglifyjs-webpack-plugin");
    // 导入webpack-merge包
    const webpackMerge = require('webpack-merge')
    // 导入基本配置文件,并将其与本文件合并后到处
    const baseConfig = require('./base.config.js')
    
    module.exports = webpackMerge(baseConfig,{
      plugins:[
        new webpack.BannerPlugin("最终版权归Carrey所有"),
        new HtmlWebpackPlugin({
          template:'index.html'
        }),
        new uglifyjsPlugin(),
      ],
    })
    View Code

        4. 至此,配置文件的拆分和合并都完成了,可以删掉原来的配置文件webpack.config.js了

      7. 配置文件合并后,无法直接使用该配置文件,会出现两个问题

        问题1:提示没有找到配置文件webpack.config.js,这是因为vue默认的配置文件名为webpack.config.js,而现在只有base.config.js文件,dev.config.js文件 和  prod.config.js文件

            解决:

              在package.json文件中人为的指定配置文件

      "scripts": {
        // 这里的./build/prod.config.js和./build/prod.config.js分别为配置文件所在路径
        "build": "webpack --config ./build/prod.config.js",
        "dev": "webpack-dev-server --open --config ./build/prod.config.js",
      },

        问题2:打包后的文件没有保存在指定的dist文件中,而是在配置文件 prod.config.js 的路径下      

            这是因为在base.config.js中,output出口文件路径为 path: path.resolve(__dirname, 'dist'), 这里__dirname获取的是当前路径,即合并到prod.config.js 后的路径(即 prod.config.js 的路径)

           解决:

              在出口文件中的路径改为:path: path.resolve(__dirname, '../dist')  返回上一层的dist文件夹中,实际在哪根据需要修改

  • 相关阅读:
    Java的栈和队列
    Spring @Scheduled 在tomcat容器里面执行两次
    Java calendar获取月份注意事项
    mysql 查询今天,昨天,上个月sql语句 注解
    MySQL 查询最近几天的记录 最近7天的记录 本周内的记录
    关于mybatis 注解sql sum(参数)传参写法
    tomcat 部署war项目
    maven项目生成war包
    Cron表达式
    ### 获取当前日期的函数
  • 原文地址:https://www.cnblogs.com/carreyBlog/p/14060262.html
Copyright © 2011-2022 走看看