Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 345|回复: 0

webpack 创建vue项目过程中遇到的问题和解决方法

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-5-8 20:02:21 | 显示全部楼层 |阅读模式

    目录 

      1 webpack简介

      2 webpack实现多个输入输出多个html

      3  webpack 中的module下rules 下的use和loader选项

      4 webpack 文件更新,如何使页面重新加载,而不是使用缓存,hash(版本号更新)

      5 webpack output 里面的publicPath 

      6 webpack热加载 热更新 热替换

      7 webpack dev-server 和nginx服务器之间的关系

      8 webpack 构建的vue项目总是会出现内容先于样式出现的很乱的页面的情况,这种情况下可以对各个vue文件里面的style样式进行抽取打包

      9  一个很好的webpack文章  什么是按需加载

      10 vue-webpack项目各个插件的应用

      11 webpack调试工具  source map 和 devtools是前端调试工具

      12 webpack自动为css样式添加前缀autoprefixer 时可能遇到-webkit- 和-moz-的前缀都没有了,而只有-o-的前缀,可能是autoprefixer 指定最新的两个版本的问题

            13 webpack在dev-server里配置autoRewrite:true 解决接口有重定向的情况

    1 webpack简介

    Webpack成为目前非常流行的前端构建工具,Webpack的工作方式是:把项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。他与grunt和gulp之间的主要区别就是webpack可以进行按需加载 按需引入;

    2 webpack实现多个输入输出多个html

    entry:{
            main: './src/main.js',
            login: './src/login.js'
        },
    
    plugins: [
            new HtmlWebpackPlugin({
                filename: 'index.html',
                template: './src/index.html',
                chunks: ['main']   //将main.js插入到index.html内部,
            }),
    
            new HtmlWebpackPlugin({
                filename: 'login.html',
                template: './src/login.html',
                chunks: ['login']
            })
    
        ],

    3  webpack 中的module下rules 下的use和loader选项

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

    文档中介绍的使用use 而实际项目中需要使用loader否则编译会报错

     

    4 webpack 文件更新,如何使页面重新加载,而不是使用缓存,hash(版本号更新)

    new HtmlWebpackPlugin({
      filename: __dirname + '/resource/zm_insurance/zm_list.html', //这个路径要相对于output.path输出的JS设置 在JS的上一级就用 ../../
      chunks: ['zmQzq'], //限定这个模板只引入index 和公用部分JS common.js
      hash: true, // 为静态资源生成hash值 在引入资源地址后加上?hash值 实现不修改文件名
      xhtml: true, // 需要符合xhtml的标准
      inject: 'body',
      template: __dirname + '/resource/zm_insurance/zm_list.ejs' //模板地址
    }),

    5 webpack output 里面的publicPath 

    当开发路径和输出路径的静态资源文件的相对关系不同的情况下

    Q:output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',   //这样在index.html文件中引入css和js将会带有dist 如 ‘/dist/main.css’
        filename: 'build.js'
       },

    既然path里有dist了,为什么publicPath: '/dist/'还要再写进去?

    A:publicPath处理静态资源引用地址用的 比如在 CSS 中引用了图片
    打包后默认情况是 url(文件名) 这样必须确保资源文件和 CSS 处于同一目录
    但我们显然不希望这样 希望修改打包引用地址 修改为 img 目录下的资源 就需要这个参数了

    就像项目里面的当我加上publicPath:'/dist'  在对应的文件中将会引入相同的路径加文件名

    <script type="text/javascript" src="/dist/login.js"></script></body>

    详见 https://www.cnblogs.com/gaomingchao/p/6911762.html

     

    当然也可以使用Url-loader使开发路径和输出路径的静态资源文件的相对关系相同

                {
                    test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
                    loader: 'url-loader',
                    options: {
                      limit: 10,
                      name:'images/[name].[ext]'
                    }
                },
                {
                    test: /\.(mp3)(\?.*)?$/,
                    loader: 'url-loader',
                    options: {
                      name:'audios/[name].[ext]',
                      limit:10
                    }
                }
    

      

     6 webpack热加载 热更新 热替换

     热更新的时候不需要关闭服务器,直接重新部署项目就行。冷的自然就是关闭服务器后再操作

      (1) 热更新  运行如下命令 实现自动刷新

      webpack-dev-server --hot --inline 自动刷新

        或者

    devServer: {
            contentBase: "./public",//本地服务器所加载的页面所在的目录
            historyApiFallback: true,//不跳转
            inline: true, //实时刷新
            host: "192.168.0.232", //本机的局域网ip
            open: true //是否运行成功后直接打开页面
        }

    执行之后直接打开页面

    "scripts": {

        "server": "webpack-dev-server --open"

      },

      (2) 热加载 装HtmlWebpackPlugin插件就可以

    plugins: [
            new HtmlWebpackPlugin({
                template: './index.html'
            }),
            new ExtractTextPlugin('[name]-[hash:3].css'), //css随机数
            new webpack.HotModuleReplacementPlugin(), //热加载插件
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': '"development"'
            }),
            new webpack.NoErrorsPlugin()
        ]

      (3) 热替换模块 详见 https://webpack.docschina.org/guides/hot-module-replacement

    全称是Hot Module ReplaceMent(HMR),理解成热模块替换或者模块热替换都可以吧,和.net中的热插拔一个意思,就是在运行中对程序的模块进行更新。这个功能主要是用于开发过程中,对生产环境没有任何帮助(这一点区别.net热插拔)。效果上就是界面的无刷新更新。

     

    7 webpack dev-server 和nginx服务器之间的关系

    wepack开启的服务器与nginx没有关系,各自独立,都可以进行反向代理,可以写三个webpack文件,一个是base 一个dev环境,一个线上环境

    dev开发环境需要进行热更新反向代理等,

    线上环境若运行在nginx服务上,不需要进行反向代理,但是一般需要加上hash值进行版本号更新,以及压缩打包合并等操作

    dev和pro环境可以是单独文件也可以merge到base文件下 ,导入base文件,之后

    const webpackBaseConfig = require('./webpack.base.config.js');

    module.exports = merge(webpackBaseConfig, {})

    //webpack.base.config.js
    
    const path = require('path')
    const webpack = require('webpack')
    const ExtractTextPlugin = require('extract-text-webpack-plugin')
    
    module.exports = {
        entry:{
            main: './src/main.js',
            login: './src/login.js'
        },
        output:{
            filename:'[name].js',
            path:path.resolve(__dirname,'./dist')
        },
        module:{
            rules:[
                {
                    test:/\.vue$/,
                    use:[{
                        loader:'vue-loader',
                        options: {
                            loaders: {
                                css: ExtractTextPlugin.extract({
                                    use: ['css-loader'],
                                    fallback: 'vue-style-loader'
                                })
                            }
                        }
                    }]
                },
                {
                    test:/\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/
                },
                {
                    test: /\.css$/,
                    use:ExtractTextPlugin.extract({
                        fallback:'style-loader',
                        use:['css-loader']
                    })
                },
                {
                    test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
                    loader: 'url-loader',
                    options: {
                      limit: 10,
                      name:'images/[name].[ext]'
                    }
                },
                {
                    test: /\.(mp3)(\?.*)?$/,
                    loader: 'url-loader',
                    options: {
                      name:'audios/[name].[ext]',
                      limit:10
                    }
                }
            ]
        },
        resolve: {
            alias: {
                'vue$': 'vue/dist/vue.esm.js'
            }
        }
    }
    //webpack.dev.config.js

    const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const merge = require('webpack-merge'); const webpackBaseConfig = require('./webpack.base.config.js'); const fs = require('fs'); fs.open('./src/config/env.js', 'w', function (err, fd) { const buf = 'export default "development";'; fs.write(fd, buf, 0, buf.length, 0, function (err, written, buffer){}); }); module.exports = merge(webpackBaseConfig, { devtool: '#source-map', output: { publicPath: '/dist/', filename: '[name].js', chunkFilename: '[name].chunk.js' }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: './src/index.html', chunks: ['main'], hash:true }), new HtmlWebpackPlugin({ filename: 'login.html', template: './src/login.html', chunks: ['login'] }), new ExtractTextPlugin({ filename: '[name].[hash].css', allChunks: true }), ], devServer: { contentBase:'./dist', port: 9091, inline:true, open:true, proxy: { '/projectName/': { // 注意此处链接的是测试服务器的地址 target:'', changeOrigin: true, secure: false } } } });

      

    //webpack.prod.config.js

    const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin'); const merge = require('webpack-merge'); const webpackBaseConfig = require('./webpack.base.config.js'); const fs = require('fs'); fs.open('./src/config/env.js', 'w', function (err, fd) { const buf = 'export default "production";'; fs.write(fd, buf, 0, buf.length, 0, function (err, written, buffer){}); }); module.exports = merge(webpackBaseConfig, { output: { filename: '[name].[hash].js', chunkFilename: '[name].[hash].chunk.js' }, plugins: [ new CleanWebpackPlugin(['dist/*'], __dirname), new ExtractTextPlugin({ filename: '[name].[hash].css', allChunks: true }), new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }), // new webpack.optimize.UglifyJsPlugin({ // compress: { // warnings: false // } // }), new HtmlWebpackPlugin({ filename: 'index.html', template: './src/index.html', chunks: ['main'], hash:true }), new HtmlWebpackPlugin({ filename: 'login.html', template: './src/login.html', chunks: ['login'] }), ] });
    //package.json 内
    "scripts": { "init": "webpack --progress --config webpack.dev.config.js", "dev": "webpack-dev-server --content-base ./ --open --inline --hot --compress --history-api-fallback --config webpack.dev.config.js", "build": "webpack --hide-modules --config webpack.prod.config.js" },  

    注意此时的package.json文件的依赖需要安装一下

    "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-plugin-component": "^1.1.0",
        "clean-webpack-plugin": "^0.1.19",
        "css-loader": "^0.28.9",
        "extract-text-webpack-plugin": "^3.0.2",
        "file-loader": "^1.1.6",
        "html-webpack-plugin": "^2.30.1",
        "style-loader": "^0.19.1",
        "url-loader": "^0.6.2",
        "vue-loader": "^13.7.0",
        "vue-router": "^3.0.1",
        "vue-template-compiler": "^2.5.13",
        "webpack": "^3.10.0",
        "webpack-dev-server": "^2.11.0",
        "webpack-merge": "^4.1.2"
      },

    这样运行项目时,分别顺序运行下面的指令,在上线提交之前一定注意在运行一下npm run build ,将环境写为线上环境

      npm run init  初始化

      npm run build 生产环境

      npn run dev 开发环境

     

    8 webpack 构建的vue项目总是会出现内容先于样式出现的很乱的页面的情况,这种情况下可以对各个vue文件里面的style样式进行抽取打包

    利用ExtractTextPlugin将css文件进行抽取打包为一个css文件,自动打包时就会将css文件插入到被需要的文件的头部,会先于内容进行加载. 

    但是每个组件可能会有样式冲突,在每个vue组件的style标签上加上scoped 就可以在设置为该样式在该组件中应用.

     

    9一个很好的webpack文章  什么是按需加载

    https://blog.csdn.net/JdoOudDm7i/article/details/62042659

    https://segmentfault.com/q/1010000009122066

    http://element.eleme.io/#/zh-CN/component/quickstart

     

    10 vue-webpack项目各个插件的应用

    1 babel一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。

    babel介绍 http://www.ruanyifeng.com/blog/2016/01/babel.html

    .babelrc文件编写 https://excaliburhan.com/post/babel-preset-and-plugins.html

    babel一系列的插件

    http://www.css88.com/doc/webpack2/   详细的webpack学习网站

    http://www.css88.com/doc/webpack2/plugins

     

    webpack 使用实例

    https://github.com/Tencent/weui.js

    https://github.com/Tencent/weui

     

     11 webpack调试工具  source map(引入时会使得webpack最终打包的js文件非常大) 和 devtools是前端调试工具

    sourcemap是为了解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术, source-map都是webpack中devtool的配置选项

    在webpack.config.js 中设置devtool: '#inline-source-map' 在浏览器中打开

     

     12 webpack自动为css样式添加前缀autoprefixer 时可能遇到-webkit- 和-moz-的前缀都没有了,而只有-o-的前缀,可能是autoprefixer 指定最新的两个版本的问题

    首先安装postcss-loader 和 autoprefixer(自动添加前缀的插件);

    npm install --save-dev postcss-loader autoprefixer
    

    在webpack配置文件中添加postcss-loader,在根目录新建postcss.config.js,并添加如下代码之后,重新使用npm start打包时,写的css会自动根据Can i use里的数据添加不同前缀了。  

    //webpack.config.js  
    module.exports = {  
        ...  
        module: {  
            rules: [  
                {  
                    test: /\.css$/,  
                    use: [  
                        {  
                            loader: "style-loader"  
                        }, {  
                            loader: "css-loader",  
                            options: {  
                                modules: true  
                            }  
                        }, {  
                            loader: "postcss-loader"  
                        }  
                    ]  
                }  
            ]  
        }  
    }  
    // postcss.config.js  
    module.exports = {  
        plugins: [  
            require('autoprefixer')  
        ]  
    }  
    

     

    但是需要注意的是autoprefixer-loader已经过时,而且默认 指定版本为最新的两个版本,

    而最新版得 -webkit- google 浏览器已经支持不带-webkit-前缀的的类似于linear-gradient(right, #fff, rgba(255, 255, 255, 0));的属性;

    https://www.npmjs.com/package/autoprefixer-loader

    13 webpack对于接口有重定向的情况处理

     devServer: {
        port: port,
        host: IP.address(),
        proxy: {
          '/api': {
            target: 'http://**:90',
            changOrigin: true,
            ws: true,
            autoRewrite: true   //处理重定向
          }
        }
      },

    14 webpack可以进行多种环境的配置

    详见  http://www.css88.com/doc/webpack2/guides/production-build/

    三种文件分别对应基本 开发和生产环境 

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 23:37 , Processed in 0.063996 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表