溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

使用webpack怎么構(gòu)建一個(gè)vue項(xiàng)目

發(fā)布時(shí)間:2021-03-11 16:00:20 來源:億速云 閱讀:161 作者:Leah 欄目:web開發(fā)

這篇文章給大家介紹使用webpack怎么構(gòu)建一個(gè)vue項(xiàng)目,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

 "devDependencies": {
  "autoprefixer-loader": "^3.2.0",
  "babel-core": "^6.18.2",
  "babel-loader": "^6.2.7",
  "babel-plugin-transform-runtime": "^6.15.0",
  "babel-preset-es2015": "^6.18.0",
  "babel-preset-stage-0": "^6.16.0",
  "babel-runtime": "^6.18.0",
  "css-loader": "^0.25.0",
  "debug": "^2.2.0",
  "express": "^4.14.0",
  "extract-text-webpack-plugin": "^1.0.1",
  "file-loader": "^0.9.0",
  "html-webpack-plugin": "^2.24.1",
  "jquery": "^3.1.1",
  "less": "^2.7.1",
  "less-loader": "^2.2.3",
  "style-loader": "^0.13.1",
  "url-loader": "^0.5.7",
  "vue-hot-reload-api": "^1.2.0",
  "vue-html-loader": "^1.2.3",
  "vue-loader": "^7.3.0",
  "webpack": "^1.13.3",
  "webpack-dev-middleware": "^1.8.4",
  "webpack-dev-server": "^1.16.2",
  "webpack-hot-middleware": "^2.13.1"
 },
 "dependencies": {
  "vue": "^1.0.26",
  "vue-router": "^0.7.13"
 }

三、在項(xiàng)目目錄下新建一個(gè)名為src的目錄,里面用于存放入口文件(index.js)、項(xiàng)目源文件(html,css,js,img之類的)、組件(.vue后綴),我的src目錄結(jié)構(gòu)大致如下:

src
 -entry
   -index.js
 -pages
   -components
   -css
   -img
   -js
   -index.html
 -public

當(dāng)然,有輸入目錄,就有輸出目錄,即在項(xiàng)目目錄下新建一個(gè)output目錄,用于放置生產(chǎn)出來的各種資源文件。

四、在項(xiàng)目目錄下新建一個(gè)名為build目錄,里面用于存放各種配置文件,涉及到基礎(chǔ)配置、開發(fā)和生產(chǎn)環(huán)境、靜態(tài)服務(wù)器以及熱加載,詳細(xì)的內(nèi)容請(qǐng)看下面的代碼:

1.webpack.config.js(基礎(chǔ)配置文件)

// 引入依賴模塊
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  // 入口文件,路徑相對(duì)于本文件所在的位置,可以寫成字符串、數(shù)組、對(duì)象
  entry: {
    // path.resolve([from ...], to) 將to參數(shù)解析為絕對(duì)路徑
    index:path.resolve(__dirname, '../src/entry/index.js'),
    // 需要被提取為公共模塊的群組
    vendors:['vue','vue-router','jquery'],
  },

  // 輸出配置
  output: {
    // 輸出文件,路徑相對(duì)于本文件所在的位置
    path: path.resolve(__dirname, '../output/static/js/'),

    // 設(shè)置publicPath這個(gè)屬性會(huì)出現(xiàn)很多問題:
    // 1.可以看成輸出文件的另一種路徑,差別路徑是相對(duì)于生成的html文件;
    // 2.也可以看成網(wǎng)站運(yùn)行時(shí)的訪問路徑;
    // 3.該屬性的好處在于當(dāng)你配置了圖片CDN的地址,本地開發(fā)時(shí)引用本地的圖片資源,上線打包時(shí)就將資源全部指向CDN了,如果沒有確定的發(fā)布地址不建議配置該屬性,特別是在打包圖片時(shí),路徑很容易出現(xiàn)混亂,如果沒有設(shè)置,則默認(rèn)從站點(diǎn)根目錄加載
    // publicPath: '../static/js/',

    // 基于文件的md5生成Hash名稱的script來防止緩存
    filename: '[name].[hash].js',
    // 非主入口的文件名,即未被列在entry中,卻又需要被打包出來的文件命名配置
    chunkFilename: '[id].[chunkhash].js'
  },

  // 其他解決方案
  resolve: {
    // require時(shí)省略的擴(kuò)展名,遇到.vue結(jié)尾的也要去加載
    extensions: ['','.js', '.vue'],
    // 模塊別名地址,方便后續(xù)直接引用別名,無須寫長長的地址,注意如果后續(xù)不能識(shí)別該別名,需要先設(shè)置root
    alias:{}
  },  

  // 不進(jìn)行打包的模塊
  externals:{},

  // 模塊加載器
  module: {
    // loader相當(dāng)于gulp里的task,用來處理在入口文件中require的和其他方式引用進(jìn)來的文件,test是正則表達(dá)式,匹配要處理的文件;loader匹配要使用的loader,"-loader"可以省略;include把要處理的目錄包括進(jìn)來,exclude排除不處理的目錄    
    loaders: [
      // 使用vue-loader 加載 .vue 結(jié)尾的文件
      {
        test: /\.vue$/, 
        loader: 'vue-loader',
        exclude: /node_modules/  
      },
      // 使用babel 加載 .js 結(jié)尾的文件
      {
        test: /\.js$/,
        loader: 'babel',
        exclude: /node_modules/,
        query:{
          presets: ['es2015', 'stage-0'], 
          plugins: ['transform-runtime']           
        }
      }, 
      // 使用css-loader和style-loader 加載 .css 結(jié)尾的文件
      { 
        test: /\.css$/,         
        // 將樣式抽取出來為獨(dú)立的文件
        loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader"),
        exclude: /node_modules/
      },
      // 使用less-loader、css-loader和style-loade 加載 .less 結(jié)尾的文件
      { 
        test: /\.less$/,         
        // 將樣式抽取出來為獨(dú)立的文件
        loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader!less-loader"),
        exclude: /node_modules/
      },      
      // 加載圖片
      {
        test: /\.(png|jpg|gif)$/,
        loader: 'url-loader',
        query: {
          // 把較小的圖片轉(zhuǎn)換成base64的字符串內(nèi)嵌在生成的js文件里
          limit: 10000,
          // 路徑要與當(dāng)前配置文件下的publicPath相結(jié)合
          name:'../img/[name].[ext]?[hash:7]'
        }
      },
      // 加載圖標(biāo)
      {
        test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
        loader: 'file-loader',
        query: {        
          // 把較小的圖標(biāo)轉(zhuǎn)換成base64的字符串內(nèi)嵌在生成的js文件里  
          limit: 10000,
          name:'../fonts/[name].[ext]?[hash:7]',
          prefix:'font'
        }
      },       
    ]     
  },

  // 配置插件項(xiàng)
  plugins: [] 
}

2.webpack.dev.config.js(開發(fā)環(huán)境下的配置文件)

// 引入依賴模塊
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

// 引入基本配置
var config = require('./webpack.config.js');

// 必須修改原配置中網(wǎng)站運(yùn)行時(shí)的訪問路徑,相當(dāng)于絕對(duì)路徑,修改完之后,當(dāng)前配置文件下的很多相對(duì)路徑都是相對(duì)于這個(gè)來設(shè)定;
// 注意:webpack-dev-server會(huì)實(shí)時(shí)的編譯,但是最后的編譯的文件并沒有輸出到目標(biāo)文件夾,而是保存到了內(nèi)存當(dāng)中
config.output.publicPath = '/';

// 重新配置模塊加載器
config.module= {
  // test是正則表達(dá)式,匹配要處理的文件;loader匹配要使用的loader,"-loader"可以省略;include把要處理的目錄包括進(jìn)來,exclude排除不處理的目錄    
  loaders: [
    // 使用vue-loader 加載 .vue 結(jié)尾的文件
    {
      test: /\.vue$/, 
      loader: 'vue-loader',
      exclude: /node_modules/  
    },
    // 使用babel 加載 .js 結(jié)尾的文件
    {
      test: /\.js$/,
      loader: 'babel',
      exclude: /node_modules/,
      query:{
        presets: ['es2015', 'stage-0'], 
        plugins: ['transform-runtime']           
      }
    }, 
    // 使用css-loader、autoprefixer-loader和style-loader 加載 .css 結(jié)尾的文件
    { 
      test: /\.css$/,         
      // 將樣式抽取出來為獨(dú)立的文件
      loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader"),
      exclude: /node_modules/
    },
    // 使用less-loader、autoprefixer-loader、css-loader和style-loade 加載 .less 結(jié)尾的文件
    { 
      test: /\.less$/,         
      // 將樣式抽取出來為獨(dú)立的文件
      loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader!less-loader"),
      exclude: /node_modules/
    },      
    // 加載圖片
    {
      test: /\.(png|jpg|gif)$/,
      loader: 'url-loader',
      query: {
        // 把較小的圖片轉(zhuǎn)換成base64的字符串內(nèi)嵌在生成的js文件里
        limit: 10000,
        // 路徑和生產(chǎn)環(huán)境下的不同,要與修改后的publickPath相結(jié)合
        name: 'img/[name].[ext]?[hash:7]'
      }
    },
    // 加載圖標(biāo)
    {
      test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
      loader: 'file-loader',
      query: {          
        limit: 10000,
        // 路徑和生產(chǎn)環(huán)境下的不同,要與修改后的publickPath相結(jié)合
        name:'fonts/[name].[ext]?[hash:7]',
        prefix:'font'
      }
    },       
  ]     
};

// 重新配置插件項(xiàng)
config.plugins = [
  // 位于開發(fā)環(huán)境下
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: '"development"'
    }
  }),

  // 自動(dòng)生成html插件,如果創(chuàng)建多個(gè)HtmlWebpackPlugin的實(shí)例,就會(huì)生成多個(gè)頁面
  new HtmlWebpackPlugin({
    // 生成html文件的名字,路徑和生產(chǎn)環(huán)境下的不同,要與修改后的publickPath相結(jié)合,否則開啟服務(wù)器后頁面空白
    filename: 'src/pages/index.html',
    // 源文件,路徑相對(duì)于本文件所在的位置
    template: path.resolve(__dirname, '../src/pages/index.html'),
    // 需要引入entry里面的哪幾個(gè)入口,如果entry里有公共模塊,記住一定要引入
    chunks: ['vendors','index'],
    // 要把<script>標(biāo)簽插入到頁面哪個(gè)標(biāo)簽里(body|true|head|false)
    inject: 'body',
    // 生成html文件的標(biāo)題
    title:''
    // hash如果為true,將添加hash到所有包含的腳本和css文件,對(duì)于解除cache很有用
    // minify用于壓縮html文件,其中的removeComments:true用于移除html中的注釋,collapseWhitespace:true用于刪除空白符與換行符
  }),  

  // 提取css單文件的名字,路徑和生產(chǎn)環(huán)境下的不同,要與修改后的publickPath相結(jié)合
  new ExtractTextPlugin("[name].[contenthash].css"),  

  // 提取入口文件里面的公共模塊
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendors',
    filename: 'vendors.js',
  }),  

  // 為組件分配ID,通過這個(gè)插件webpack可以分析和優(yōu)先考慮使用最多的模塊,并為它們分配最小的ID
  new webpack.optimize.OccurenceOrderPlugin(),

  // 模塊熱替換插件
  new webpack.HotModuleReplacementPlugin(),

  // 允許錯(cuò)誤不打斷程序
  new webpack.NoErrorsPlugin(),

  // 全局掛載插件
  new webpack.ProvidePlugin({
    $:"jquery",
    jQuery:"jquery",
    "window.jQuery":"jquery"
  })    
];

// vue里的css也要單獨(dú)提取出來
config.vue = {
  loaders: {
    css: ExtractTextPlugin.extract("css")
  }
};

// 啟用source-map,開發(fā)環(huán)境下推薦使用cheap-module-eval-source-map
config.devtool='cheap-module-eval-source-map';

// 為了實(shí)現(xiàn)熱加載,需要?jiǎng)討B(tài)向入口配置中注入 webpack-hot-middleware/client ,路徑相對(duì)于本文件所在的位置
// var devClient = 'webpack-hot-middleware/client';
// 為了修改html文件也能實(shí)現(xiàn)熱加載,需要修改上面的devClient變量,引入同級(jí)目錄下的dev-client.js文件
var devClient = './build/dev-client';
// Object.keys()返回對(duì)象的可枚舉屬性和方法的名稱
Object.keys(config.entry).forEach(function (name, i) {
  var extras = [devClient];
  config.entry[name] = extras.concat(config.entry[name]);
})

module.exports = config;

3.webpack.prod.config.js(生產(chǎn)環(huán)境下的配置文件)

// 引入依賴模塊
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

// 引入基本配置
var config = require('./webpack.config');

// 重新配置插件項(xiàng)
config.plugins = [
  // 位于生產(chǎn)環(huán)境下
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: '"production"'
    }
  }),

  // 自動(dòng)生成html插件,如果創(chuàng)建多個(gè)HtmlWebpackPlugin的實(shí)例,就會(huì)生成多個(gè)頁面
  new HtmlWebpackPlugin({
    // 生成html文件的名字,路徑相對(duì)于輸出文件所在的位置
    filename: '../../html/index.html',
    // 源文件,路徑相對(duì)于本文件所在的位置
    template: path.resolve(__dirname, '../src/pages/index.html'),
    // 需要引入entry里面的哪幾個(gè)入口,如果entry里有公共模塊,記住一定要引入
    chunks: ['vendors','special','index'],
    // 要把<script>標(biāo)簽插入到頁面哪個(gè)標(biāo)簽里(body|true|head|false)
    inject: 'body',
    // 生成html文件的標(biāo)題
    title:'',
    // hash如果為true,將添加hash到所有包含的腳本和css文件,對(duì)于解除cache很有用
    // minify用于壓縮html文件,其中的removeComments:true用于移除html中的注釋,collapseWhitespace:true用于刪除空白符與換行符
  }),   

  // 提取css單文件的名字,路徑相對(duì)于輸出文件所在的位置
  new ExtractTextPlugin("../css/[name].[contenthash].css"),  

  // 提取入口文件里面的公共模塊
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendors',
    filename: 'vendors.js',
  }),  
  
  // 壓縮js代碼
  new webpack.optimize.UglifyJsPlugin({
    compress: {
      warnings: false
    },
    // 排除關(guān)鍵字,不能混淆
    except:['$','exports','require']
  }),

  // 為組件分配ID,通過這個(gè)插件webpack可以分析和優(yōu)先考慮使用最多的模塊,并為它們分配最小的ID
  new webpack.optimize.OccurenceOrderPlugin(),

  // 全局掛載插件,當(dāng)模塊使用這些變量的時(shí)候,wepback會(huì)自動(dòng)加載,區(qū)別于window掛載
  new webpack.ProvidePlugin({
    $:"jquery",
    jQuery:"jquery",
    "window.jQuery":"jquery"
  })  
];

// vue里的css也要單獨(dú)提取出來
config.vue = {
  loaders: {
    css: ExtractTextPlugin.extract("css")
  }
};

// 開啟source-map,生產(chǎn)環(huán)境下推薦使用cheap-source-map或source-map,后者得到的.map文件體積比較大,但是能夠完全還原以前的js代碼
config.devtool='source-map';
// 關(guān)閉source-map
// config.devtool=false;

module.exports = config;

4.dev-server.js(服務(wù)器配置文件)

// 引入依賴模塊
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.dev.config.js');

// 創(chuàng)建一個(gè)express實(shí)例
var app = express();

// 對(duì)網(wǎng)站首頁的訪問返回 "Hello World!" 字樣
app.get('/', function (req, res) {
  res.send('Hello World!');
});

// 調(diào)用webpack并把配置傳遞過去
var compiler = webpack(config);

// 使用 webpack-dev-middleware 中間件,搭建服務(wù)器
var devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: config.output.publicPath,
  stats: {
    colors: true,
    chunks: false
  }
})

// 使用 webpack-hot-middleware 中間件,實(shí)現(xiàn)熱加載
var hotMiddleware = require('webpack-hot-middleware')(compiler);

// 為了修改html文件也能實(shí)現(xiàn)熱加載,使用webpack插件來監(jiān)聽html源文件改變事件
compiler.plugin('compilation', function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
    // 發(fā)布事件
    hotMiddleware.publish({ action: 'reload' });
    cb();
  })
});

// 注冊中間件
app.use(devMiddleware);
app.use(hotMiddleware);

// 監(jiān)聽 8888 端口,開啟服務(wù)器
app.listen(8888, function (err) {
  if (err) {
    console.log(err);
    return;
  }
  console.log('Listening at http://localhost:8888');
})

5.dev-client.js(配合dev-server.js監(jiān)聽html文件改動(dòng)也能夠觸發(fā)自動(dòng)刷新)

// 引入 webpack-hot-middleware/client 
var hotClient = require('webpack-hot-middleware/client');

// 訂閱事件,當(dāng) event.action === 'reload' 時(shí)執(zhí)行頁面刷新
hotClient.subscribe(function (event) {
  if (event.action === 'reload') {
    window.location.reload();
  }
})

五、為了不必每次構(gòu)建項(xiàng)目都要輸入webpack --display-modules --display-chunks --config build/webpack.config.js這條長命令,我們在package.js文件中修改“scripts”項(xiàng):

"scripts": {
 "build":"webpack --display-modules --display-chunks --config build/webpack.config.js",
 "dev":"node ./build/dev-server.js"
}

關(guān)于使用webpack怎么構(gòu)建一個(gè)vue項(xiàng)目就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI