webpack從零開始第6課:在Vue開發中使用webpack

webpack目錄css


本文參考文檔
vue   vuex   vue-router   vue-loader   awesome-vue精彩的vue       vue-clihtml

寫在前面
vue官方已經寫好一個vue-webpack模板vue_cli,本來本身寫一個,發現官方寫得已經夠好了,本身寫顯得有點多餘,但爲了讓你們熟悉webpack,決定仍是一步一步從0開始寫,但源文件就直接拷貝官方的vue

準備工做html5

  1. 新建文件夾D:\03www2018\study\vue2017,下面根目錄指的就是這個目錄
  2. 生成package.json, 根目錄>cnpm init
  3. 安裝webpack和webpack開發服務器, 根目錄>cnpm i -D webpack webpack-dev-server
  4. 安裝vue、vuex、vue-router,根目錄>cnpm i -S vue vuex vue-router
  5. 下載vue_cli的webpack模板中src這個源文件夾根目錄\src
  6. 經常使用必裝loader, 根目錄>cnpm i -D xxxxxnode

    • eslint-loader + eslint 代碼規範
    • babel-core babel核心
    • babel-preset-env
    • babel-preset-stage-0
    • babel-loader
    • less + less-loader或其它css預處理器,如sass+sass-loader
    • css-loader 導入css文件
    • style-loader 將css文件注入到style標籤中
    • postcss-loader
    • html-loader
    • url-loader + file-loader 處理圖片/音頻視頻/字體,不建議單獨使用file-loader
    • vue-loader + css-loader + vue-template-compiler 導入vue組件
  7. 經常使用必裝plugin,第三方插件安裝cnpm i -D xxx-webpack-pluginreact

    • html-webpack-plugin
    • extract-text-webpack-plugin
  8. webpack和webpack-dev-server配置webpack

    // 根目錄>build/webpack.base.conf.js
    module.exports = {
    const path = require('path')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const ExtractTextPlugin = require('extract-text-webpack-plugin')
    module.exports = {
      // 第一部分: 文件的輸入和輸出
      context: path.resolve(__dirname, '../src'),
      entry: './main',
      output: {
        path: path.resolve(__dirname, '../dist'),
        filename: './app.js' // dist文件夾不存在時,會自動建立
      },
      // 第二部分: 效率方面
      resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': path.resolve('src')
        }
      },
      // 第三部分:處理不一樣的模塊類型,分js+vue|react類,圖片,樣式,音頻視頻,字體幾大塊
      module: {
        rules: [
          // 01----js部分
          // eslint規範代碼
          // babel實現js兼容,以便瀏覽器識別
          // 識別vue組件
          {
            test: /\.js$/, // 對js文件使用eslint來檢查代碼的規範
            loader: 'eslint-loader',
            enforce: 'pre', // 但爲了保險,建議單獨給eslint-loader指定pre值,有關loader的優先級,參考https://webpack.js.org/configuration/module/#rule-enforce
            include: [path.resolve('src')], // 只有些目錄下的js文件才使用eslint-loader
            options: {}
          },
          {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: {}
          },
          // 02----圖片部分
          {
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: 'url-loader',
            options: {
              limit: 10,
              outputPath: 'static/',
              name: 'img/[name].[hash:7].[ext]' //最後生成的圖片完整路徑是 output.path+ outputPath+name
            }
          },
          // 03----樣式處理
          {
            test: /\.css$/,
            use: ExtractTextPlugin.extract({
              fallback: 'style-loader',
              use: 'css-loader'
            })
          }
          // 04----音頻視頻
    
          // 05----字體
        ]
      },
      // 第四部分:插件,功能不少
      plugins: [
        // 01----生產首頁
        new HtmlWebpackPlugin({
          title: 'hello,零和壹在線課堂', // html5文件中<title>部分
          filename: 'index.html', // 默認是index.html,服務器中設置的首頁是index.html,若是這裏改爲其它名字,那麼devServer.index改成和它同樣
          // 也是 context+template是最後模板的完整路徑,./不能少
          template: './index.html', // 若是以爲插件默認生成的hmtl5文件不合要求,能夠指定一個模板,模板文件若是不存在,會報錯,默認是在項目根目錄下找模板文件,才模板爲樣板,將打包的js文件注入到body結尾處
          inject: 'body' // true|body|head|false,四種值,默認爲true,true和body相同,是將js注入到body結束標籤前,head將打包的js文件放在head結束前,false是不注入,這時得要手工在html中加js
    
        }),
        new ExtractTextPlugin('styles.css')
      ],
      // 第五部分: 服務器的配置
      devServer: {
        contentBase: path.join(__dirname, "../dist"), //網站的根目錄爲 根目錄/dist,若是配置不對,會報Cannot GET /錯誤
        port: 9000, //端口改成9000
        open: true
      }
    }
    
    }
  9. package.json配置git

    {
     "name": "vue2017",
     "version": "1.0.0",
     "description": "",
     "main": "index.js",
     "scripts": {
    "a": "webpack --config ./build/webpack.base.conf.js",
    "b": "webpack-dev-server --config ./build/webpack.base.conf.js",
    "test": "echo \"Error: no test specified\" && exit 1"
     },
     "author": "",
     "license": "ISC",
     "devDependencies": {
    "eslint": "^4.14.0",
    "eslint-loader": "^1.9.0",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.9.7"
     },
     "dependencies": {
    "vue": "^2.5.13",
    "vue-router": "^3.0.1",
    "vuex": "^3.0.1"
     }
    }
  10. .eslintrc.js配置github

    // cnpm i -D eslint-plugin-html
    // cnpm i -D babel-eslint
    // cnpm i -D eslint-config-standard (依賴 eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard)
    module.exports = {
      root: true,
      parser: 'babel-eslint', // 默認的解析器爲espree,這裏指定爲 babel-eslint,參考 https://github.com/babel/babel-eslint
      parserOptions: { // 解析器的選項,默認支持  ECMAScript 5
        sourceType: 'module'
      },
      env: {
        browser: true, // 環境定義爲瀏覽器
      },
      // https://github.com/standard/standard/blob/master/docs/RULES-en.md
      extends: 'standard',
      plugins: [ //第3方插件 eslint-plugin-html,
        'html'
      ],
      rules: {
        'generator-star-spacing': 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
      }
     }

安裝vue
D:\03www2018\study\webpack2018>cnpm i vue -Sweb

若是有下面的報錯

[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

(found in <Root>)
解釋: 運行時構建不包含模板編譯器,所以不支持 template 選項,只能用 render 選項,但即便使用運行時構建,在單文件組件中也依然能夠寫模板,由於單文件組件的模板會在構建時預編譯爲 render 函數
修改 D:/03www2018/study/webpack2018/build/webpackfile.js
resolve: {
        alias: {
            'vue': 'vue/dist/vue.js'
        }
    },

最簡單的例子

D:\03www2018\study\webpack2018\today\wang\home.js
import Vue from 'vue';
const app = new Vue({
  template: '<div>hello wolr</div>'
}).$mount('#main')

導入第一個vue組件

// D:\03www2018\study\webpack2018\today\wang\home.js
import App from "./app.vue"
import Vue from 'vue';
const app = new Vue({
  template: '<App />',
  components:{App}
}).$mount('#main')
// D:\03www2018\study\webpack2018\today\wang\App.vue 
<template>
<div>上午好</div>
</template>

報錯

Uncaught Error: Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.

安裝並配置 vue-loader

官方文檔 https://vue-loader.vuejs.org/...
D:\03www2018\study\webpack2018>cnpm i vue-loader -D

提示要安裝css-loader和vue-template-compiler,如今將這兩個也一塊兒安裝

D:\03www2018\study\webpack2018>cnpm i css-loader vue-template-compiler -D

如今就能夠正常顯示vue組件

處理css文件

// D:\03www2018\study\webpack2018\today\wang\app.css
body{
    color:#09f;
}

處理單獨的css文件
沒有裝css-loader會報錯

ERROR in ./today/wang/app.css
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.

安裝和配置

官方文檔: https://webpack.js.org/loader...
D:\03www2018\study\webpack2018>cnpm i -D css-loader
{
    test: /\.css$/,
    loader: 'css-loader', 
},

對上面導入的css通常有兩種處理,一是使用style-loader將css嵌入到html文件的style標籤中,一種是單獨存在一個文件中

style-loader

官方文檔: https://webpack.js.org/loader...
D:\03www2018\study\webpack2018>cnpm i style-loader -D
{
    test: /\.css$/,
    loader: 'style-loader!css-loader', 
},

多個loader是從右到左執行,多個loader之間用!鏈接,上面多個loader也能夠寫在數組的形式

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

這種寫法是,從下到上執行,先執行css-loader再執行style-loader

將css文件單獨打包到一個文件
這要使用到ExtractTextWebpackPlugin插件

處理less/sass等文件

這要用到less-loader或sass-loader,同時得安裝less或sass,若是沒安裝會報錯

[Vue warn]: Error in beforeCreate hook: "Error: Cannot find module "!!vue-loader/node_modules/vue-style-loader!css-loader!../../node_modules/_vue-loader@13.6.0@vue-loader/lib/style-compiler/index?{"vue":true,"id":"data-v-381730fa","scoped":false,"hasInlineConfig":false}!less-loader!../../node_modules/_vue-loader@13.6.0@vue-loader/lib/selector?type=styles&index=0&bustCache!./app.vue""

ave組件的內容

<template>
    <div class='morning'>上午好</div>
</template>
<style lang='less'>
    @color:#f96;
    .morning{
        color:@color
    }
</style>

安裝less和less-loader

D:\03www2018\study\webpack2018>cnpm i -D less less-loader

配置

{
    test: /\.css$/,
    use: ExtractTextPlugin.extract({
    // fallback: "style-loader", //備用,若是提取不成功時,會使用style-loader來處理css
    use: "css-loader"
    })
    /*use: [
    { loader: "style-loader" },
    { loader: "css-loader" }
    ]*/
}, 

{
    test: /\.less$/,
    use: [
         {
             loader: "style-loader" // creates style nodes from JS strings
         },
        {
        loader: "css-loader" // translates CSS into CommonJS
        },
        {
        loader: "less-loader" // compiles Less to CSS
        }
    ]
},

上面這個例子,只有導入的css文件單單獨存在一個文件中,vue組件中的less歸到了style中了,

說明:在vue組件<style>中,若是lang="less",在vue-loader中默認配置好了less,無須另外配置
說明: 上面例子是配置的是單獨的less文件,不適合uve中的less
說明:如何將vue中的less也放到單獨的css文件中呢? 參考 https://vue-loader.vuejs.org/...
{
    test: /\.vue$/,
    loader: 'vue-loader',
    options: {
        extractCSS: true
    }
}

但上面有個缺點,會覆蓋以前css中的配置中生成style.css文件,如何解決呢?

const path = require('path');
const webpack = require('webpack')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");

const extractCSS = new ExtractTextPlugin('css/[name]-one.css');
const extractLESS = new ExtractTextPlugin('css/[name]-two.css');

module.exports={    
    plugins: [
        extractCSS,
        extractLESS
    ],
    
    module: {
        rules: [
            
             {
                test: /\.css$/,
                use: extractCSS.extract({
                 // fallback: "style-loader", //備用,若是提取不成功時,會使用style-loader來處理css
                 use: "css-loader"
                })
        
            }, 

              {
                  test: /\.vue$/,
                  loader: 'vue-loader',
                  options: {
                     // extractCSS: true
                     extractCSS: function(){
                         return extractLESS
                     }
                    }
                }
        ]
    },  
}

導入圖片

// D:\03www2018\study\webpack2018\today\wang\App.vue中增長圖片
<template>
    <div class='morning'>
    <img src="../images/logo.jpg" />
    <img src="../images/a.jpg" />
    上午好
    </div>
</template>
<style lang='less'>
    @color:#f96;
    .morning{
        color:@color
    }
</style>

若是安裝並配置好了url-loader,圖片會生成data:image格式
發現生成<img src="data:image/jpeg;base64,bW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcHVibGljX3BhdGhfXyArICIzNDk0NWM0MDMyMWQyMDk3YTY5Zjg2MGZkNWQ1M2FlZC5qcGciOw==">,可是不顯示出圖片,url-loader不配置會顯示圖片,顯示以下<img src="34945c40321d2097a69f860fd5d53aed.jpg">

安裝
D:03www2018studywebpack2018>cnpm i url-loader -D

安裝D:03www2018studywebpack2018>cnpm i file-loader -D

相關文章
相關標籤/搜索