美文网首页
webpack搭建本地服务器(六)

webpack搭建本地服务器(六)

作者: 未路过 | 来源:发表于2022-06-12 15:04 被阅读0次

    26 搭建本地服务器

    1. 为什么要搭建本地服务器?

    08_babel对JS-Vue处理_19.jpg

    我们希望当文件变化,自动帮我们打包,并且显示到页面上。

    2. Webpack watch

    08_babel对JS-Vue处理_20.jpg

    其实webpacl --watch是会被webpack-cli自动处理,变成watch:true

    package.json  
    "scripts": {
        "build": "webpack ---watch "
      },
    webpack-cli会帮助处理这个watch这个选项,把这个watch配置改成true
    
    或者直接在webpack.config.js 里面添加watch:ture
    const {VueLoaderPlugin } = require("vue-loader/dist/index");
    module.exports = {
      //设置模式
      //development 开发阶段,会设置development
      //production 准备打包上线的时候,设置production
        mode:"development",
      devtool:"source-map",
      watch:ture,
    

    以上配置完成后,运行npm run build,然后会打包。接下来在改变js里面的内容,一旦保存,就会自动打包。但是index.html必须重新刷新之后才能显示重新打包后的内容。

    3. Webpack-dev-server的使用

    08_babel对JS-Vue处理_21.jpg
    //步骤一: npm install webpack-dev-server -d
    //步骤二:安装之后,在package.json里面写入serve
      "scripts": {
        "build": "webpack",
        "serve":"webpack serve"
      },
    //npm run serve实质上也是利用webpackcli帮助我们启动了一个本地服务器
    //并且使用serve的时候,不需要专门设置watch为ture,因为dev-serve本身会给我们监听文件的变化。然后会对当前文件做编译,进行打包
    //其实dev-serve是基于express框架搭建的本地服务器,这个服务器里面,有打包好的静态资源,返回给浏览器
    

    但其实,这个使用并没有输出打包好的文件。也就是启动npm run serve 并没有产生build文件夹。其实webpack cli是有对源代码进行打包的,但是打包之后的代码没有做输出,而是放到了内存里面。目标是提高开发效率,如果是express从build文件夹里面读取文件的话,需要读取,转化成字节流,但是如果从内存读取的话,就是直接处理字节流。

    4.配置devServer

    4.1 配置static

    可以在webpack.config.js文件中配置devServer

    module.exports = {
      //...
      devServer: {
        static: '/abc',
      },
    };
    

    npm run serve之后

    显示

    <i> [webpack-dev-server] Content not from webpack is served from './abc' directory

    如果webpack的静态资源中没有这个文件,将从index.html同级的abc文件夹中去加载。

    如果没有copywebpackplugin这个插件设置的话,这时候既可以吧static改成"./public"。static里面这个文件夹,也会被打包。开发阶段使用contentBase,打包的时候使用copywebpackplugin

      new CopyWebpackPlugin({
          patterns:[
            {
              from:"public",
              globOptions:{
                ignore:[
                  "**/index.html"
                ]
              }
            }
          ]
        }),
    

    4.2. 配置HMR

    一.什么是模块热替换
    08_babel对JS-Vue处理_22.jpg

    11111我们不希望浏览器随随便便刷新。在webpack里面,一个文件可以看出一个模块,使用热更新的时候,只有被更改或者替换,删除的模块才会被重新加载,其他的模块的状态是不会改变的。

    二.设置模块热替换
    a.对指定模块进行热替换。
    module.exports = {
      //...
        target:"web"
      devServer: {
        static: '/abc',
        hot:true
      },
    };
         //一般情况下,设置 hot为ture的时候,我们会再设置一个target属性,这两个得同时打开
          
    

    这时候再element.js里面的console.log('aaa')改成bbb,发现并没有热替换,而是全部都重新刷新了,这是因为devserver并不知刀要热更新哪个模块,所以所有模块都重新加载了。这时候我们需要修改文件的引入方式,

    08_babel对JS-Vue处理_23.jpg

    以前在main.js里面是这么引入的import "./js/elment.js",现在需要这么引入

    import "./js/element.js"//第一次加载需要
    if(module.hot){
      module.hot.accept("./js/element.js", () => {
        console.log('element.js文件被更改');
      })
    

    这样就可以进行热替换了。第一次运行npm run serve

    [HMR] Waiting for update signal from WDS...
    element.js:1 i am element.js file
    element.js:26 ccc
    main.js:40 50
    main.js:41 ¥99.88
    main.js:44 abc
    main.js:44 cba
    main.js:44 nba
    main.js:45 123
    index.js:551 [webpack-dev-server] Hot Module Replacement enabled.
    index.js:551 [webpack-dev-server] Live Reloading enabled.
    

    更改element.js里面的ccc

    [HMR] Waiting for update signal from WDS...
    element.js:1 i am element.js file
    element.js:26 ccc
    main.js:40 50
    main.js:41 ¥99.88
    main.js:44 abc
    main.js:44 cba
    main.js:44 nba
    main.js:45 123
    index.js:551 [webpack-dev-server] Hot Module Replacement enabled.
    index.js:551 [webpack-dev-server] Live Reloading enabled.
    The deferred DOM Node could not be resolved to a valid node.
    index.js:551 [webpack-dev-server] App updated. Recompiling...
    index.js:551 [webpack-dev-server] App hot update...
    log.js:24 [HMR] Checking for updates on the server...
    element.js:1 i am element.js file
    element.js:26 ddd
    main.js:34 element.js文件被更改
    log.js:24 [HMR] Updated modules:
    log.js:24 [HMR]  - ./src/js/element.js
    log.js:24 [HMR] App is up to date.
    

    16, 17, 18行就重新被打印出来了,其他模块没有变化。

    b.对全部模块进行热替换。
    08_babel对JS-Vue处理_24.jpg

    对于vue框架里面的文件处理来说,我们有vue-loader,来帮我们处理.vue文件。vue-loader在帮我们处理这个文件的过程中,已经帮我们设置出了加载这些文件时候的 module.hot.accept()等等的js代码了。

    c.HMR的原理
    08_babel对JS-Vue处理_25.jpg 08_babel对JS-Vue处理_26.jpg

    4.3 配置hotOnly等

    08_babel对JS-Vue处理_27.jpg 08_babel对JS-Vue处理_28.jpg

    本来是浏览器请求bundle.js,服务器返回bundle.js但是如果文件过大的话,就是效率比较慢,这时候最好压缩。直接返回bundle.gzip,浏览器发现文件时gzip格式,就会自动给文件解压,。index.html默认不会压缩.

    module.export = {
     devServer:{
        static:'./abc',
        hot:true,
        host:"localhost",
        port:8080,
        open:true,
        compress:true
    
      },
    }
    

    4.4 配置Proxy

    08_babel对JS-Vue处理_29.jpg

    跨域就是在当前的域名下面,去发送其他的http 请求,这个就是跨域。(概念:只要协议、域名、端口有任何一个不同,都被当作是不同的域。)

    08_babel对JS-Vue处理_30.jpg

    4.5 配置historyApiFallback

    08_babel对JS-Vue处理_31.jpg

    4.6 配置resolve

    08_babel对JS-Vue处理_32.jpg
    a.确认是文件还是文件夹
    08_babel对JS-Vue处理_33.jpg
    b.extensions和alias的配置
    08_babel对JS-Vue处理_34.jpg

    27 webpack开发和生产环境分离

    一下的config的话,运行nom run build的话,就会按照config的配置去打包,但是这是我们开发的时候的配置,比如mode和devtool,还有插件cleanwebpackpluin

    09_webpack服务器和VueCLI_17.jpg
    const path = require("path");
    const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const { DefinePlugin } = require("webpack");
    const CopyWebpackPlugin = require('copy-webpack-plugin');
    const { VueLoaderPlugin } = require('vue-loader/dist/index');
    
    module.exports = {
      target: "web",
      mode: "development",
      devtool: "source-map",
      entry: "./src/main.js",
      output: {
        path: path.resolve(__dirname, "./build"),
        filename: "js/bundle.js",
      },
      devServer: {
        contentBase: "./public",
        hot: true,
        host: "0.0.0.0",
        port: 7777,
        open: true,
        // compress: true,
        proxy: {
          "/api": {
            target: "http://localhost:8888",
            pathRewrite: {
              "^/api": ""
            },
            secure: false,
            changeOrigin: true
          }
        }
      },
      resolve: {
        extensions: [".js", ".json", ".mjs", ".vue", ".ts", ".jsx", ".tsx"],
        alias: {
          "@": path.resolve(__dirname, "./src"),
          "js": path.resolve(__dirname, "./src/js")
        }
      },
      module: {
        rules: [
          {
            test: /\.css$/,
            use: ["style-loader", "css-loader", "postcss-loader"],
          },
          {
            test: /\.less$/,
            use: ["style-loader", "css-loader", "less-loader"],
          },
          // },
          {
            test: /\.(jpe?g|png|gif|svg)$/,
            type: "asset",
            generator: {
              filename: "img/[name]_[hash:6][ext]",
            },
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024,
              },
            },
          },
          {
            test: /\.(eot|ttf|woff2?)$/,
            type: "asset/resource",
            generator: {
              filename: "font/[name]_[hash:6][ext]",
            },
          },
          {
            test: /\.js$/,
            loader: "babel-loader"
          },
          {
            test: /\.vue$/,
            loader: "vue-loader"
          }
        ],
      },
      plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
          template: "./public/index.html",
          title: "哈哈哈哈"
        }),
        new DefinePlugin({
          BASE_URL: "'./'",
          __VUE_OPTIONS_API__: true,
          __VUE_PROD_DEVTOOLS__: false
        }),
        // new CopyWebpackPlugin({
        //   patterns: [
        //     {
        //       from: "public",
        //       to: "./",
        //       globOptions: {
        //         ignore: [
        //           "**/index.html"
        //         ]
        //       }
        //     }
        //   ]
        // }),
        new VueLoaderPlugin()
      ],
    };
    
    

    我们想分离这个配置文件,在目录底下新建一个config文件夹,里面创建三个文件

    1.webpack.comm.config.js

    2.webpack.dev.config.js

    3.webpack.prod.config.js

    然后修改package.json文件

      "scripts": {
        "build": "webpack --config ./config/webpack.prod.config.js",
        "serve": "webpack serve --config ./config/webpack.dev.config.js"
      },
    

    npm i webpack-merge -d

    a.webpack.comm.config.js

    const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const { DefinePlugin } = require("webpack");
    const { VueLoaderPlugin } = require('vue-loader/dist/index');
    
    module.exports = {
      target: "web",
      entry: "./src/main.js",
      output: {
        path: path.resolve(__dirname, "../build"),
        filename: "js/bundle.js",
      },
      resolve: {
        extensions: [".js", ".json", ".mjs", ".vue", ".ts", ".jsx", ".tsx"],
        alias: {
          "@": path.resolve(__dirname, "../src"),
          "js": path.resolve(__dirname, "../src/js")
        }
      },
      module: {
        rules: [
          {
            test: /\.css$/,
            use: ["style-loader", "css-loader", "postcss-loader"],
          },
          {
            test: /\.less$/,
            use: ["style-loader", "css-loader", "less-loader"],
          },
          // },
          {
            test: /\.(jpe?g|png|gif|svg)$/,
            type: "asset",
            generator: {
              filename: "img/[name]_[hash:6][ext]",
            },
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024,
              },
            },
          },
          {
            test: /\.(eot|ttf|woff2?)$/,
            type: "asset/resource",
            generator: {
              filename: "font/[name]_[hash:6][ext]",
            },
          },
          {
            test: /\.js$/,
            loader: "babel-loader"
          },
          {
            test: /\.vue$/,
            loader: "vue-loader"
          }
        ],
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: "./public/index.html",
          title: "哈哈哈哈"
        }),
        new DefinePlugin({
          BASE_URL: "'./'",
          __VUE_OPTIONS_API__: true,
          __VUE_PROD_DEVTOOLS__: false
        }),
        new VueLoaderPlugin()
      ],
    };
    
    

    b.webpack.dev.config.js

    const { merge } = require('webpack-merge');
    
    const commonConfig = require('./webpack.comm.config');
    
    module.exports = merge(commonConfig, {
      mode: "development",
      devtool: "source-map",
      devServer: {
        contentBase: "./public",
        hot: true,
        // host: "0.0.0.0",
        port: 7777,
        open: true,
        // compress: true,
        proxy: {
          "/api": {
            target: "http://localhost:8888",
            pathRewrite: {
              "^/api": ""
            },
            secure: false,
            changeOrigin: true
          }
        }
      },
    })
    
    

    c. webpack.prod.config.js

    const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    const CopyWebpackPlugin = require('copy-webpack-plugin');
    const {merge} = require('webpack-merge');
    
    const commonConfig = require('./webpack.comm.config');
    
    module.exports = merge(commonConfig, {
      mode: "production",
      plugins: [
        new CleanWebpackPlugin(),
        new CopyWebpackPlugin({
          patterns: [
            {
              from: "./public",
              globOptions: {
                ignore: [
                  "**/index.html"
                ]
              }
            }
          ]
        }),
      ]
    })
    
    
    09_webpack服务器和VueCLI_18.jpg

    相关文章

      网友评论

          本文标题:webpack搭建本地服务器(六)

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