一 webpack 2.0 及用到的插件安裝(默認已經有node環境)
1. package.json文件 (插件安裝及插件的功能不詳解)
{ "private": true, "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": "^5.8.38", "clean-webpack-plugin": "^0.1.15", "css-loader": "^0.25.0", "debug": "^2.2.0", "express": "^4.14.0", "extract-text-webpack-plugin": "^2.0.0", "file-loader": "^0.9.0", "html-webpack-plugin": "^2.24.1", "node-sass": "^4.5.0", "postcss-loader": "^1.3.2", "sass-loader": "^6.0.2", "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", "vue-resource": "^1.2.1", "webpack": "^2.2.1", "webpack-dev-middleware": "^1.8.4", "webpack-dev-server": "^1.16.2", "webpack-hot-middleware": "^2.13.1" }, "dependencies": { "vue": "^2.0.0", "vue-router": "^2.0.0" }, "scripts": { "build": "webpack --display-modules --display-chunks --config webpack.prod.config.js", "dev": "cross-env webpack --hide-modules --display-chunks --config webpack.dev.config.js", "test": "cross-env webpack --config webpack.config.js" } }
注明:scripts 設置了一些執行的命令 如dev 就是執行dev環境下webpack編譯用的命令 控制台之行:npm run dev即可
2.webpack 配置文件 (有些配置的路徑 按項目改變)
(1)webpack.config.js
var path = require('path'); var webpack = require('webpack'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { /* 輸入文件 */ entry: { // path.resolve([from ...], to) 將to參數解析為絕對路徑 index:path.resolve(__dirname, './resources/js/src/index.js'), // 需要被提取為公共模塊的群組 vendors:['vue','vue-router','three','convex'], }, output: { /* 輸出目錄,沒有則新建 */ path: path.resolve(__dirname, './public/js/'), /* 靜態目錄,可以直接從這里取文件 */ //publicPath: './resources/js/dist/', /* 文件名 */ filename: '[name].[hash].js', }, resolve:{ extensions: ['.js', '.css', '.scss','.vue'], alias: { 'vue$': path.resolve(__dirname,'./node_modules/vue/dist/vue.js'), 'vue-router$':path.resolve(__dirname,'./node_modules/vue-router/dist/vue-router.js'), 'three$':path.resolve(__dirname,'./resources/js/lib/threejs/build/three.min.js'), 'convex$':path.resolve(__dirname,'./resources/js/lib/convex.js'), } }, module: { rules: [ /* 用來解析vue后綴的文件 */ { test: /\.vue$/, use: ['vue-loader'] }, /* 用babel來解析js文件並把es6的語法轉換成瀏覽器認識的語法 */ { test: /\.js$/, loader: 'babel-loader', /* 排除模塊安裝目錄的文件 */ exclude: /node_modules/, options:{ presets: ['es2015', 'stage-0'], plugins: ['transform-runtime'] } }, { test: /\.css$/, // 將樣式抽取出來為獨立的文件 loader: ExtractTextPlugin.extract({fallback:"style-loader", use:["css-loader","postcss-loader"]}), exclude: /node_modules/ }, // 使用less-loader、autoprefixer-loader、css-loader和style-loade 加載 .less 結尾的文件 { test: /\.scss$/, // 將樣式抽取出來為獨立的文件 use:['style-loader','css-loader','autoprefixer-loader','sass-loader'], exclude: /node_modules/ }, // 加載圖片 { test: /\.(png|jpg|gif)$/, loader: 'url-loader', options: { // 把較小的圖片轉換成base64的字符串內嵌在生成的js文件里 limit: 10000, // 路徑和生產環境下的不同,要與修改后的publickPath相結合 name: 'img/[name].[ext]?[hash:7]' } }, // 加載圖標 { test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/, loader: 'file-loader', options: { limit: 10000, // 路徑和生產環境下的不同,要與修改后的publickPath相結合 name:'fonts/[name].[ext]?[hash:7]', prefix:'font' } } ] }, //devtool: '#eval-source-map', }
注明:webpack2.0中loader名稱要補全 如sass-loader 之前可以省略-loader這樣的后綴 但是現在必須寫全 否則無法編譯
2.webpack.dev.conifg.js
// 引入依賴模塊 var path = require('path'); var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var CleanWebpackPlugin = require('clean-webpack-plugin'); // 引入基本配置 var config = require('./webpack.config.js'); // 必須修改原配置中網站運行時的訪問路徑,相當於絕對路徑,修改完之后,當前配置文件下的很多相對路徑都是相對於這個來設定; // 注意:webpack-dev-server會實時的編譯,但是最后的編譯的文件並沒有輸出到目標文件夾,而是保存到了內存當中 config.output.publicPath = '/game/laravel-master/public/js/'; // 重新配置插件項 config.plugins = [ // 位於開發環境下 new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"development"' } }), // 自動生成html插件,如果創建多個HtmlWebpackPlugin的實例,就會生成多個頁面 new HtmlWebpackPlugin({ // 生成html文件的名字,路徑和生產環境下的不同,要與修改后的publickPath相結合,否則開啟服務器后頁面空白 filename: '../../resources/views/dist/index.blade.php', // 源文件,路徑相對於本文件所在的位置 template: path.resolve(__dirname, './resources/views/index.blade.php'), // 需要引入entry里面的哪幾個入口,如果entry里有公共模塊,記住一定要引入 chunks: ['vendors','index'], // 要把<script>標簽插入到頁面哪個標簽里(body|true|head|false) inject: 'body', // 生成html文件的標題 title:'' // hash如果為true,將添加hash到所有包含的腳本和css文件,對於解除cache很有用 // minify用於壓縮html文件,其中的removeComments:true用於移除html中的注釋,collapseWhitespace:true用於刪除空白符與換行符 }), // 提取css單文件的名字,路徑和生產環境下的不同,要與修改后的publickPath相結合 new ExtractTextPlugin("[name].[contenthash].css"), // 提取入口文件里面的公共模塊 new webpack.optimize.CommonsChunkPlugin({ name: 'vendors', filename: 'vendors.js', }), new CleanWebpackPlugin(['js','views','css'],{ root:path.resolve(__dirname, './public/'), verbose: true, dry: false, //exclude: ['shared.js'] }), new CleanWebpackPlugin(['views/dist'],{ root:path.resolve(__dirname, './resources/'), verbose: true, dry: false, //exclude: ['shared.js'] }), // 為組件分配ID,通過這個插件webpack可以分析和優先考慮使用最多的模塊,並為它們分配最小的ID //new webpack.optimize.OccurenceOrderPlugin(), // 模塊熱替換插件 //new webpack.HotModuleReplacementPlugin(), // 允許錯誤不打斷程序 //new webpack.NoErrorsPlugin(), // 全局掛載插件 new webpack.ProvidePlugin({ Vue: "vue", THREE:'three' }) ]; module.exports = config;
注明:HtmlWebpackPlugin inject 最好還是配置為body 會規避一些問題 (如 渲染速度 加載時序等)
二 vue項目
1。項目結構 (用的laravel php框架 webpack中的部分路徑與該項目結構一致)

2.看下主視圖文件 index.blade.php (這個文件由於用的laravel框架 目前沒找到怎么改后綴名)
<!DOCTYPE html> <html> <head> <title>Laravel</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> </head> <body> <div id="app"> </div> <script type="text/javascript" src="/game/laravel-master/public/js/vendors.js"></script><script type="text/javascript" src="/game/laravel-master/public/js/index.f6c1bc018a4da91a571e.js"></script></body> </html>
注明:視圖文件 什么都沒做 就放一個用於vue實例掛載的元素 js文件也是用webpack編譯后插入的
3. resources - js - src -index.js 項目的入口文件(es6語法)
import App from './pages/app.vue'; import VueRouter from 'vue-router'; import VueResource from 'vue-resource'; Vue.use(VueRouter); Vue.use(VueResource); const main = resolve => { require.ensure(['./pages/main.vue'],()=>{ resolve(require('./pages/main.vue')) }) } const router = new VueRouter({ routes: [{ path:'/page', component: main, } ] }) Vue.http.options.emulateJSON = true; Vue.http.interceptors.push((request, next) =>{ next((response) => { return response }); }); const app = new Vue({ router:router, render: h => h(App), }).$mount('#app')
注明:創建了Vue實例並掛載在id為app的元素上,並創建了一個簡單的路由實例
4.app.vue 文件 什么也沒做 就是使用<router-view></router-view>標簽,它用於渲染匹配的組件 和 加載一個common.scss文件設置一些頁面全局樣式
<template>
<router-view></router-view>
</template>
<script>
export default {
components: {
}
}
</script>
<style scoped lang='sass-loader'>
@import '../../../css/src/common.scss';
</style>
5.main.vue 基本上寫了單頁面組件所有能用到常用屬性
<template>
<div class="data-webgl-main" ref="canvasbox">
<canvas ref="canvas"></canvas>
</div>
</template>
<script >
export default{
//監聽父傳遞的變量和函數
props:[
],
//聲明用到組件
components:{
},
//組建的數據
data () {
return {
vinit:'',
vscene:'',
vcamera:'',
vrenderer:'',
vlight:'',
vgeometry:'',
vmaterial:'',
vcube: '',
vsphere:'',
vline:'',
vspGroup:'',
vhullMesh:'',
vcloud:''
}
},
//組建加載完執行
mounted (){
this.vscene = new THREE.Scene();
this.vcamera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
this.vrenderer = new THREE.WebGLRenderer({canvas:this.$refs.canvas,antialias : true});
this.finitRender();
this.finitCamera();
this.finitScene();
this.finitLight();
this.finitMesh();
//this.fgeneratePoints();
this.fcreatePointCloud(3,true,0.6,true, 0xffffff);
this.frender();
},
//組建被創建觸發
created () {
},
//監聽路由和一些變量的變化出發 監聽函數要注意 this的指向
watch:{
},
//組建用到的所有方法
methods:{
frender (){
// this.vrenderer.clear();
// this.vcamera.position.x = this.vcamera.position.x + 1;
// this.vcube.rotation.x += 0.02;
// this.vcube.rotation.y += 0.02;
// this.vcube.rotation.z += 0.02;
// this.vline.rotation.z += 0.01;
// this.vspGroup.rotation.y = this.vhullMesh.rotation.y;
// this.vhullMesh.rotation.y += 0.01;
var vertices = this.vcloud.geometry.vertices;
vertices.forEach(function (v) {
v.y = v.y - (v.velocityY);
v.x = v.x - (v.velocityX);
if (v.y <= 0) v.y = 60;
if (v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -1;
});
this.vrenderer.render(this.vscene, this.vcamera);
requestAnimationFrame(this.frender);
},
finitRender (){
this.vrenderer.setClearColor(0x000000,1.0);
this.vrenderer.shadowMapEnabled = true;
this.vrenderer.setSize(window.innerWidth,window.innerHeight);
},
finitCamera (){
this.vcamera.position.x = 20;
this.vcamera.position.y = 40;
this.vcamera.position.z = 110;
// this.vcamera.up.x = 0;
// this.vcamera.up.y = 0;
// this.vcamera.up.z = 0;
this.vcamera.lookAt(new THREE.Vector3(20, 30, 0))
},
finitScene (){
},
finitLight (){
// let light = new THREE.AmbientLight(0xFFFFFF);
// light.position.set(100, 100, 200);
// this.vscene.add(light);
// light = new THREE.PointLight(0x00FF00);
// light.position.set(0, 0,300);
// this.vscene.add(light);
// let light = new THREE.SpotLight(0xFFFFFF);
// light.position.set(-40,60,-10);
// light.castShadow = true;
// this.vscene.add(light);
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
this.vscene.add(ambientLight);
// add spotlight for the shadows
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
this.vscene.add(spotLight);
},
finitMesh (){
// var geometry = new THREE.CylinderGeometry( 100,150,400);
// var material = new THREE.MeshLambertMaterial( { color:0xFFFF00} );
// var mesh = new THREE.Mesh( geometry,material);
// mesh.position.add(new THREE.Vector3(0,0,0));
// var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);
// var planeMaterial = new THREE.MeshLambertMaterial({color:0xffffff});
// var plane = new THREE.Mesh(planeGeometry,planeMaterial);
// plane.rotation.x = -0.5*Math.PI;
// plane.position.x = 15;
// plane.position.y = 0;
// plane.position.z = 0;
// plane.receiveShadow = true;
// this.vscene.add(plane);
// var cubeGeometry = new THREE.CubeGeometry(4,4,4);
// var cubeMaterial = new THREE.MeshLambertMaterial({color:0xff0000,wireframe:false});
// var cube = new THREE.Mesh(cubeGeometry,cubeMaterial);
// cube.position.x = -4;
// cube.position.y = 3;
// cube.position.z = 0;
// cube.castShadow = true;
// this.vcube = cube;
// this.vscene.add(cube);
// var sphereGeometry = new THREE.SphereGeometry(4,20,20);
// var sphereMaterial = new THREE.MeshLambertMaterial({color:0x7777ff,wireframe:false});
// var sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
// sphere.position.x = 20;
// sphere.position.y = 4;
// sphere.position.z = 2;
// this.vsphere = sphere;
// this.vscene.add(sphere);
// this.vcube = new THREE.Mesh();
// var mats = [];
// mats.push(new THREE.MeshBasicMaterial({color:0x009e60}))
// mats.push(new THREE.MeshBasicMaterial({color:0x0051ba}))
// mats.push(new THREE.MeshBasicMaterial({color:0xffd500}))
// mats.push(new THREE.MeshBasicMaterial({color:0xff5800}))
// mats.push(new THREE.MeshBasicMaterial({color:0xc41e3a}))
// mats.push(new THREE.MeshBasicMaterial({color:0xffffff}))
// var faceMaterial = new THREE.MeshFaceMaterial(mats);
// for(var x=0;x<3;x++){
// for(var y = 0;y<3;y++){
// for(var z=0;z<3;z++){
// var cubeGeom = new THREE.CubeGeometry(2.9,2.9,2.9);
// var cube = new THREE.Mesh(cubeGeom,faceMaterial);
// cube.position.add(new THREE.Vector3(x*3-3,y*3,z*3-3));
// this.vcube.add(cube);
// }
// }
// }
// this.vscene.add(this.vcube)
// var points = this.fgosper(4, 60);
// var lines = new THREE.Geometry();
// var colors = [];
// var i = 0;
// points.forEach(function (e) {
// lines.vertices.push(new THREE.Vector3(e.x, e.z, e.y));
// colors[i] = new THREE.Color(0xffffff);
// colors[i].setHSL(e.x / 100 + 0.5, ( e.y * 20 ) / 300, 0.8);
// i++;
// });
// lines.colors = colors;
// var material = new THREE.LineBasicMaterial({
// opacity: 1.0,
// linewidth: 1,
// vertexColors: THREE.VertexColors
// });
// this.vline = new THREE.Line(lines, material);
// this.vline.position.set(25, -30, -60);
// this.vscene.add(this.vline);
},
fgosper (a, b) {
var turtle = [0, 0, 0];
var points = [];
var count = 0;
rg(a, b, turtle);
return points;
function rt(x) {
turtle[2] += x;
}
function lt(x) {
turtle[2] -= x;
}
function fd(dist) {
// ctx.beginPath();
points.push({x: turtle[0], y: turtle[1], z: Math.sin(count) * 5});
// ctx.moveTo(turtle[0], turtle[1]);
var dir = turtle[2] * (Math.PI / 180);
turtle[0] += Math.cos(dir) * dist;
turtle[1] += Math.sin(dir) * dist;
points.push({x: turtle[0], y: turtle[1], z: Math.sin(count) * 5});
// ctx.lineTo(turtle[0], turtle[1]);
// ctx.stroke();
}
function rg(st, ln, turtle) {
st--;
ln = ln / 2.6457;
if (st > 0) {
// ctx.strokeStyle = '#111';
rg(st, ln, turtle);
rt(60);
gl(st, ln, turtle);
rt(120);
gl(st, ln, turtle);
lt(60);
rg(st, ln, turtle);
lt(120);
rg(st, ln, turtle);
rg(st, ln, turtle);
lt(60);
gl(st, ln, turtle);
rt(60);
}
if (st == 0) {
fd(ln);
rt(60);
fd(ln);
rt(120);
fd(ln);
lt(60);
fd(ln);
lt(120);
fd(ln);
fd(ln);
lt(60);
fd(ln);
rt(60)
}
}
function gl(st, ln, turtle) {
st--;
ln = ln / 2.6457;
if (st > 0) {
// ctx.strokeStyle = '#555';
lt(60);
rg(st, ln, turtle);
rt(60);
gl(st, ln, turtle);
gl(st, ln, turtle);
rt(120);
gl(st, ln, turtle);
rt(60);
rg(st, ln, turtle);
lt(120);
rg(st, ln, turtle);
lt(60);
gl(st, ln, turtle);
}
if (st == 0) {
lt(60);
fd(ln);
rt(60);
fd(ln);
fd(ln);
rt(120);
fd(ln);
rt(60);
fd(ln);
lt(120);
fd(ln);
lt(60);
fd(ln);
}
}
},
fgeneratePoints() {
// add 10 random spheres
var points = [];
for (var i = 0; i < 20; i++) {
var randomX = -15 + Math.round(Math.random() * 30);
var randomY = -15 + Math.round(Math.random() * 30);
var randomZ = -15 + Math.round(Math.random() * 30);
points.push(new THREE.Vector3(randomX, randomY, randomZ));
}
this.vspGroup = new THREE.Object3D();
var material = new THREE.MeshBasicMaterial({color: 0xff0000, transparent: false});
points.forEach((point) => {
var spGeom = new THREE.SphereGeometry(0.2);
var spMesh = new THREE.Mesh(spGeom, material);
spMesh.position.copy(point);
this.vspGroup.add(spMesh);
});
// add the points as a group to the scene
this.vscene.add(this.vspGroup);
// use the same points to create a convexgeometry
var hullGeometry = new THREE.ConvexGeometry(points);
this.vhullMesh = this.fcreateMesh(hullGeometry);
this.vscene.add(this.vhullMesh);
},
fcreateMesh (geom) {
// assign two materials
var meshMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00, transparent: true, opacity: 0.2});
meshMaterial.side = THREE.DoubleSide;
var wireFrameMat = new THREE.MeshBasicMaterial();
wireFrameMat.wireframe = true;
// create a multimaterial
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
return mesh;
},
fcreatePointCloud(size, transparent, opacity, sizeAttenuation, color) {
var texture = THREE.ImageUtils.loadTexture("laravel-master/resources/images/textures/particles/raindrop-3.png");
var geom = new THREE.Geometry();
var material = new THREE.ParticleBasicMaterial({
size: size,
transparent: transparent,
opacity: opacity,
map: texture,
blending: THREE.AdditiveBlending,
sizeAttenuation: sizeAttenuation,
color: color
});
var range = 40;
for (var i = 0; i < 20; i++) {
var particle = new THREE.Vector3(
Math.random() * range - range / 2,
Math.random() * range * 1.5,
Math.random() * range - range / 2);
particle.velocityY = 0.1 + Math.random() / 5;
particle.velocityX = (Math.random() - 0.5) / 3;
geom.vertices.push(particle);
}
this.vcloud = new THREE.ParticleSystem(geom, material);
this.vcloud.sortParticles = true;
this.vscene.add(this.vcloud);
}
},
//屬性的一個實時計算
computed:{
},
}
</script>
<style lang="sass-loader" scoped>
@import '../../../css/src/main.scss';
</style>
未完待續。。。。。。
