webpack 建立vue項目過程當中遇到的問題和解決方法

目錄 

  1 webpack簡介javascript

  2 webpack實現多個輸入輸出多個htmlcss

  3  webpack 中的module下rules 下的use和loader選項html

  4 webpack 文件更新,如何使頁面從新加載,而不是使用緩存,hash(版本號更新)前端

  5 webpack output 裏面的publicPath vue

  6 webpack熱加載 熱更新 熱替換java

  7 webpack dev-server 和nginx服務器之間的關係node

  8 webpack 構建的vue項目老是會出現內容先於樣式出現的很亂的頁面的狀況,這種狀況下能夠對各個vue文件裏面的style樣式進行抽取打包webpack

  9  一個很好的webpack文章  什麼是按需加載ios

  10 vue-webpack項目各個插件的應用nginx

  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>

詳見 http://www.javashuo.com/article/p-wcwyzejt-gp.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/

三種文件分別對應基本 開發和生產環境 

相關文章
相關標籤/搜索