使用vue+webpack的多頁面架構(轉+本身的狀況)

按如下步驟可正常配置多頁面架構javascript

記得安裝 node-glob   安裝命令:npm install node-glob --save-devphp

文件附加css

webpack.base.conf.js --參考more start  處html

var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
var webpack=require('webpack'); //加入webpack對象

//more
var glob = require('glob'); //node-glob
var entries = getEntry('./src/views/**/*.js'); // 得到入口js文件. views替換了module
//more end
function resolve (dir) {
  return path.join(__dirname, '..', dir)
}
function getEntry(globPath) {
  var entries = {},
    basename, tmp, pathname;

  glob.sync(globPath).forEach(function (entry) {
    basename = path.basename(entry, path.extname(entry));
    tmp = entry.split('/').splice(-3);
    pathname = tmp.splice(0, 1) + '/' + basename; // 正確輸出js和html的路徑
    entries[pathname] = entry;
  });
  console.log("base-entrys:",entries);
  return entries;
}
module.exports = {
  entry:entries ,
  // entry: {
  //   app: './src/main.js'
  // },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      'basecommon':'./../../../common',//base組件引入公共樣式
      'components':'./../components',//非base組件,./../common
      'api':'./../../api',//非base組件
      'base':'./../base' //非base組件引入base組件
    }
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('images/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  },
  plugins: [  
  new webpack.ProvidePlugin({  
    $:"jquery",  
    jQuery:"jquery",  
    "windows.jQuery":"jquery"  
  })  
] 
}
View Code

webpack.dev.conf.js --參考more start  處前端

var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

//more
var path = require('path');
var glob = require('glob');
//more end

// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})

function getEntry(globPath) {
  var entries = {},
    basename, tmp, pathname;

  glob.sync(globPath).forEach(function(entry) {
    basename = path.basename(entry, path.extname(entry));
    tmp = entry.split('/').splice(-3);
    pathname = tmp.splice(0, 1) + '/' + basename; // 正確輸出js和html的路徑
    entries[pathname] = entry;
  });
  console.log("dev-entrys:",entries);
  return entries;
}

//more end

module.exports = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
  },
  // cheap-module-eval-source-map is faster for development
  devtool: '#cheap-module-eval-source-map',
  plugins: [
    new webpack.DefinePlugin({
      'process.env': config.dev.env
    }),
    // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
    // https://github.com/ampedandwired/html-webpack-plugin
    // new HtmlWebpackPlugin({
    //   filename: 'index.html',
    //   template: 'index.html',
    //   inject: true
    // }),
    new FriendlyErrorsPlugin()
  ]
})

//more start 先定義後插入
var pages = getEntry('./src/views/**/*.html');
console.log("dev pages----------------------");
for (var pathname in pages) {
  console.log("filename:" + pathname + '.html');
  console.log("template:" + pages[pathname]);
  // 配置生成的html文件,定義路徑等
  var conf = {
    filename: pathname + '.html',
    template: pages[pathname], // 模板路徑
    minify: { //傳遞 html-minifier 選項給 minify 輸出
      removeComments: true
    },
    inject: 'body', // js插入位置
    chunks: [pathname, "vendor", "manifest"] // 每一個html引用的js模塊,也能夠在這裏加上vendor等公用模塊
  };
  // 須要生成幾個html文件,就配置幾個HtmlWebpackPlugin對象
  module.exports.plugins.push(new HtmlWebpackPlugin(conf));
}
View Code

 

webpack.prod.conf.js --參考more start  處vue

var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

//more
var path = require('path');
var glob = require('glob');
//more end

var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
      sourceMap: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css')
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: {
        safe: true
      }
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
/*    new HtmlWebpackPlugin({
      filename: config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),*/
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

if (config.build.productionGzip) {
  var CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig


//more start
function getEntry(globPath) {
  var entries = {},
    basename, tmp, pathname;

  glob.sync(globPath).forEach(function(entry) {
    basename = path.basename(entry, path.extname(entry));
    tmp = entry.split('/').splice(-3);
    pathname = tmp.splice(0, 1) + '/' + basename; // 正確輸出js和html的路徑
    entries[pathname] = entry;
  });
  console.log("pro-entrys:",entries);
  return entries;
}

var pages = getEntry('./src/views/**/*.html');
console.log("pro pages----------------------");
for (var pathname in pages) {
  console.log("filename:" + pathname + '.html');
  console.log("template:" + pages[pathname]);
  // 配置生成的html文件,定義路徑等
  var conf = {
    filename: pathname + '.html',
    template: pages[pathname], // 模板路徑
    minify: { //傳遞 html-minifier 選項給 minify 輸出
      removeComments: true,
      collapseWhitespace: true,
      removeAttributeQuotes: true
    },
    inject: 'body', // js插入位置
    chunks: [pathname, "vendor", "manifest"], // 每一個html引用的js模塊,也能夠在這裏加上vendor等公用模塊
     // necessary to consistently work with multiple chunks via CommonsChunkPlugin
    chunksSortMode: 'dependency'
  };
  // 須要生成幾個html文件,就配置幾個HtmlWebpackPlugin對象
  module.exports.plugins.push(new HtmlWebpackPlugin(conf));
}



     
View Code

 

 

-----------------橫線內爲轉的-----------------------java

首先,要大概知道webpack是什麼,webpack的插件都是作什麼用的,vue是什麼,而後看完以後也能夠去補充一下這些方面的知識。node

 

 

第一步:安裝環境

 

須要安裝的有:jquery

  1. nodejs,並添加入環境變量PATH
  2. 使用nodejs安裝vue-cli 
    參考內容: 
    http://cn.vuejs.org/guide/installation.html#u547D_u4EE4_u884C_u5DE5_u5177 
    使用命令: 

    npm install -g vue-cli 
  3. 使用nodejs安裝webpack和webpack-dev-server 
    參考內容: 
    http://webpack.github.io/docs/tutorials/getting-started/ 
    使用命令: 

    npm install webpack -g 

    之因此要在全局安裝webpack是由於使用webpack的命令行方便,不須要在每個項目中到node_module中調用。
  4. Atom編輯器 
    這個從網上下載,https://atom.io/。這是一個開源的編輯器軟件,之因此選擇atom,是由於它集合了sublimeText和其餘一些編輯器的優勢。最大的好處是可使用package插件的形式對atom編輯器進行自定義擴展。

第二步:建立項目模板

vue init wepack vue-multipage-demo

如上所示,這條命令的意思是使用vue的init命令,建立一個基於webpack組件化管理的項目。這將會在D:\WS_WebStorm目錄下建立新目錄vue-multipage-demo。 
 
圖2 
如圖2,在通過設置以後,能夠看到已經生成了一個項目vue-multipage-demo,接下來須要切換到項目目錄下進行操做。在資源管理器中,咱們能夠看到已經生成了這樣的目錄: 
生成的文件結構 
圖3 
如圖3,各個文件夾和文件分別是: 
build webpack構建過程的設置文件,包括調試和發佈版本以及一些工具函數 
config 這裏是webpack-dev-server的一些設定,關於webpack和webpack-dev-server的設定,詳見官方文檔 
src 項目的源文件所在,按照你須要的樣子寫js和html文件,webpack將打包成瀏覽器可識別的,如ES6 
static 這裏是存放靜態資源的地方,在build以後會生成dist文件夾,這個文件夾中的文件會原封不動放進去 
.babelrc webpack插件babel的設置 
.editorconfig 這是atom編輯器生成的配置文件,在各個項目中能夠自由配置 
.eslintignore 使用eslint檢測代碼是否符合規則的忽略目錄,用於eslint設置 
.gitignore 使用Git版本管理時須要忽略的目錄,用於git設置 
index.html 項目生成後的入口頁面,由於vue默認是使用單頁面的,因此在webpack中同時也只有這一個入口 
package.json nodejs的配置 
README.md 說明文件,其中說明了使用vue-cli建立項目以後應該怎麼作 
dist build以後生成的目錄,其中存放webpack打包以後的結果,webpack中須要指定build規則 
表1 
npm install 
圖4 
如圖4,執行這兩條命令,切換到項目目錄下,使用npm的安裝命令,對已經生成的package.json所依賴的組件進行安裝。固然,咱們以後還會安裝一些其餘的插件。webpack

第三步:補充須要的插件

雖說,在項目開發中,插件的補充是根據需求進行增減的,可是在這個項目中,有一些基本的須要添加的插件,我在這裏提出。package.json中的代碼以下:

"dependencies": { "babel-runtime": "^6.0.0", "bootstrap": "^3.3.7", "bootstrap-table": "^1.11.0", "font-awesome": "^4.6.3", "jquery": "^3.1.0", "node-glob": "^1.2.0", "vue": "^1.0.21", "vue-resource": "^0.9.3" }, "devDependencies": { "babel-core": "^6.0.0", "babel-eslint": "^6.1.2", "babel-loader": "^6.0.0", "babel-plugin-transform-runtime": "^6.0.0", "babel-preset-es2015": "^6.0.0", "babel-preset-stage-2": "^6.0.0", "babel-register": "^6.0.0", "bootstrap-loader": "^2.0.0-beta.9", "connect-history-api-fallback": "^1.1.0", "css-loader": "^0.23.0", "dynamics.js": "^1.1.5", "eslint": "^2.10.2", "eslint-config-standard": "^5.1.0", "eslint-friendly-formatter": "^2.0.5", "eslint-loader": "^1.3.0", "eslint-plugin-html": "^1.3.0", "eslint-plugin-promise": "^1.0.8", "eslint-plugin-standard": "^1.3.2", "eventsource-polyfill": "^0.9.6", "express": "^4.13.3", "extract-text-webpack-plugin": "^1.0.1", "file-loader": "^0.8.4", "function-bind": "^1.0.2", "html-webpack-plugin": "^2.8.1", "http-proxy-middleware": "^0.12.0", "json-loader": "^0.5.4", "ora": "^0.2.0", "shelljs": "^0.6.0", "url-loader": "^0.5.7", "vue-hot-reload-api": "^1.2.0", "vue-html-loader": "^1.0.0", "vue-loader": "^8.3.0", "vue-style-loader": "^1.0.0", "webpack": "^1.13.2", "webpack-dev-middleware": "^1.4.0", "webpack-hot-middleware": "^2.6.0", "webpack-merge": "^0.8.3" }

其中包括了由項目自動生成的一些插件。 
我梳理一下,主要有下面這些,其中標註紅色的是我本身用來開發依賴的: 
dependencies: 
babel-runtime 
bootstrap 
bootstrap-table 
font-awesome 
jQuery 
node-glob 
vue 
devDependencies: 
bootstrap-loader 
dynamics.js 
那麼主要就是添加一下node-glob和vue,其餘的若是須要再進行添加。nodej-glob是用來獲取路徑的,vue是須要依賴的主要部分。

第四步:修改項目

這一步最重要。 
在咱們沒有動過以前,src目錄是這個樣子的,如圖5: 
沒動過的src 
圖5 
首先,建立以下目錄結構: 
src 

—–module 

—–index 

—–index.html 
—–main.js 
將以前外面的index.html放進來,main.js放入index,更名爲index.js,此處必定注意名稱要相同,不然後面尋找路徑時是找不到對應文件的。而後將App.vue放入components。最後是這樣的,如圖6: 
修改以後的src 
圖6 
這時候須要對文件進行必定的修改。首先是index.js,對App的調用,路徑修改,如圖7 
[圖片]

[圖片] 
圖7

修改完了上面的資源,咱們要修改webpack的配置。 
咱們介紹一下webpack在這個項目中本來的順序:因爲webpack將全部的js,css/less,html等都視爲js的可引入資源,因此入口就成了js文件。那麼webpack須要設置一個入口的js文件,這個入口的js文件就是main.js,在webpack中有一個插件,叫作html-webpack-plugin,這個是用來將js和html對應起來,也就是若干js對應一個html,在原來的項目中html就是index.html。 
在運行npm run dev 或者build以後,就會將文件打包,因爲dev的時候文件是在內存中,因此build能夠看得比較清楚,在dist目錄中,會有一個index.html,其中已經打包進了

webpack.base.conf

添加下面兩行在這裏,圖8中位置,

var glob = require('glob'); var entries = getEntry('./src/module/**/*.js'); // 得到入口js文件
  • 1
  • 2
  • 1
  • 2

[圖片] 
圖8 
這裏的glob,就是前面提到的node-glob。將entry修改成這個,圖9中位置, 
[圖片] 
圖9

而後在下面添加getEntry方法。

function getEntry(globPath) { var entries = {}, basename, tmp, pathname; glob.sync(globPath).forEach(function (entry) { basename = path.basename(entry, path.extname(entry)); tmp = entry.split('/').splice(-3); pathname = tmp.splice(0, 1) + '/' + basename; // 正確輸出js和html的路徑 entries[pathname] = entry; }); console.log("base-entrys:"); console.log(entries); return entries; }

由於咱們的想法是要將全部的業務模塊放在module中,這樣一來的話,就在module中細分,最後輸出html都在dist的module下。這裏的字符串操做也是和路徑的狀況相匹配的,若是有須要進行其餘方式的設定,注意在這裏修改路徑的識別。

webpack.dev.conf.js

在打開後,咱們會發如今這裏有一個插件的設置,如圖10: 
[圖片] 
圖10 
這個 插件就是剛纔提到的將輸出html頁面build結果的地方。 
首先,添加

var path = require('path'); var glob = require('glob');

用來引入path和glob工具。 
將圖10中的那一段去掉,由於咱們要本身來添加這個插件。 
一樣的,在這個文件中也須要添加這個函數,放在文件的下面,

function getEntry(globPath) { var entries = {}, basename, tmp, pathname; glob.sync(globPath).forEach(function(entry) { basename = path.basename(entry, path.extname(entry)); tmp = entry.split('/').splice(-3); pathname = tmp.splice(0, 1) + '/' + basename; // 正確輸出js和html的路徑 entries[pathname] = entry; }); console.log("dev-entrys:"); console.log(entries); return entries; }

而後再添加這一段,

var pages = getEntry('./src/module/**/*.html'); console.log("dev pages----------------------"); for (var pathname in pages) { console.log("filename:" + pathname + '.html'); console.log("template:" + pages[pathname]); // 配置生成的html文件,定義路徑等 var conf = { filename: pathname + '.html', template: pages[pathname], // 模板路徑 minify: { //傳遞 html-minifier 選項給 minify 輸出 removeComments: true }, inject: 'body', // js插入位置 chunks: [pathname, "vendor", "manifest"] // 每一個html引用的js模塊,也能夠在這裏加上vendor等公用模塊 }; // 須要生成幾個html文件,就配置幾個HtmlWebpackPlugin對象 module.exports.plugins.push(new HtmlWebpackPlugin(conf)); }

這個一樣是經過指定的路徑,按照我以前的預想,進行html的迭代獲取,而後對每個html進行設定。咱們的多頁面輸出關鍵也就在這個地方。 
html-webpack-plugin這個插件能夠爲一個html輸出打包對應的js模塊。chunks就是對應的js模塊,也就是webpack的入口,包括entries和使用了webpack.optimize.CommonsChunkPlugin插件聲稱的公共js模塊。這些模塊都有各自的名字,entries的名字就是前面經過getEntry函數生成的一組入口組件名稱和路徑。 
經過上面的修改,就作成了這樣一件事情:爲webpack提供多個js入口,而這些js入口和html頁面是在同一個文件夾下的,那麼它們的key或者說name就是相同的。這樣在循環的時候,就會獲取到對應的js和html,經過循環建立多個html-webpack-plugin來將不一樣的js模塊打包進對應的html,並經過webpack批量構建,在dist中就會產生咱們須要的一組html文件。而這些html文件都是已經通過壓縮的,js代碼也通過了壓縮處理。

webpack.prod.conf.js

和webpack.dev.conf.js中作相似的處理,先註釋掉原來的HtmlWebpackPlugin,而後在下面添加函數,經過迭代插入多個HtmlWebpackPlugin。

HtmlWebpackPlugin更多的設置,到webpack的官網上查看。

而後使用npm run dev或者npm run build來構建。在構建的過程當中,可能會出現一些依賴插件不存在的錯誤,須要先使用npm install –save-dev 插件名 來安裝相應的依賴插件。

這樣,index.html就被構建到了dist/module/index.html中。 
但功能是如出一轍的。 
vue的使用在這裏不贅述。這裏說明一下,咱們的module中,是系統的業務模塊,components中是功能模塊和細分的代碼模塊,也就是vue組件。因爲webpack這裏帶了babel,因此在js源文件中可使用ES6的寫法。在業務js中,就能夠經過導入,組合,自定義vue組件,來實現相應的業務需求。

其餘

好比在我如今拆分的這個網頁中,包括這麼幾個部分: 
[圖片]

[圖片]

[圖片] 
這是對一個bootstrap網站模板index頁面進行拆分後的結果,css,html都放在對應的vue中,固然,我也引入了jquery。 
vue的組件能夠實現繼承和mixin。可以很好的進行組件化開發,而經過webpack將src的源代碼進行構建變成瀏覽器可以識別的正常文件。這樣就大大下降了前端開發的重複性。

/2016-09-13 補 / 
這個是個人一個demo,提供給學生用的。 
http://www.huyangsheng.cn/resource/vue-multipage-demo.rar

以上文章是參考了幾篇以後弄出來一個適合本身用的。 
參考: 
https://github.com/Coffcer/Blog/issues/1 
http://cnu4.github.io/2016/03/21/Webpack-Vue-MultiplePage/ 
http://jiongks.name/blog/just-vue/?from=groupmessage&isappinstalled=1 
http://www.cnblogs.com/grimm/p/5768433.html 
https://github.com/yaoyao1987/vue-cli-multipage

---------------------轉發結束--------------------

相關文章
相關標籤/搜索