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

vue

View Post

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

目录 

  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/

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

以上是 webpack 创建vue项目过程中遇到的问题和解决方法 - 凉梁凉糕 的全部内容, 来源链接: utcz.com/z/376290.html

回到顶部