vue项目加webpack相关

本文详细介绍了如何配置Webpack,包括入口、出口、模块加载器、插件等,以及如何实现自定义图标、日期处理、图片懒加载、缩略图预览、上拉加载更多和文件上传等功能。同时,文章还讨论了如何通过提取CSS、按需加载Mint-UI组件和使用路由懒加载来优化项目,并提供了生产环境部署的建议。
摘要由CSDN通过智能技术生成

webpack配置

webpack.config.js

'use strict';
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin'); 
module.exports = {
    entry: {
        main: './src/main.js' // main是默认入口,也可以是多入口
    },
    // 出口, 所有产出资源路径
    output: {
        filename: './build.js', 					   // 指定js文件
        path: path.join(__dirname,'..','dist',)    // 最好是绝对路径,'..' 代表当前目录的上一级的dist
    },
    module: {
        // 一样的功能rules: webpack2.x之后新加的
        loaders:[  	// require('./a.css||./a.js')文件路径辨别require的哪些需要load
            {
                test: /\.css$/,  // $结尾
             	loader:'style-loader!css-loader!autoprefixer-loader',  // 顺序是反过来的2!1
            },
            {
                test: /\.less$/,
                loader: 'style-loader!css-loader!autoprefixer-loader!less-loader'
            },
            {
                test: /\.(jpg|png|svg|ttf|woff|woff2|gif)$/,
                // 顺序是反过来的2!1,ext后缀名
                loader: 'url-loader?limit=4096&name=[name].[ext]', 
                options: {       		// 常用
                    limit:4096, 		// 4096字节以上生成文件,否则base64
                    name:'[name].[ext]' // [name].[ext]内置提供的,因为本身是先读这个文件
                }
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                options: {
                    presets: ['es2015'],             // 关键字
					plugins: ['transform-runtime'],  // 函数
				}
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },                                                                               
    plugins: [
        // 插件的执行顺序是依次执行的
        new htmlWebpackPlugin({
            template:'./src/index.html',
        })
        // 将src下的template属性描述的文件根据当前配置的output.path,将文件移动到该目录
    ]
}

自定义图标

vender-mui-dist-css-mui.css

/*引入自定义的字体图标*/
@font-face {
    font-family: Muiicons;
    font-weight: normal;
    font-style: normal;
    src: url('../fonts/iconfont.ttf') format('truetype');
}
/*引入自定义的样式*/
.icon-shouye1:before {content: "\e6cc";}
.icon-diamond:before {content: "\e653";}
.icon-huiyuan1:before {content: "\e60f";}
.icon-gouwucheman:before {content: "\e600";}
.icon-huiyuan:before {content: "\e61f";}
.icon-huiyuan2:before {content: "\e601";}
.icon-icon:before {content: "\e602";}

moment:JavaScript 日期处理类库

moment:http://momentjs.cn/

安装:

npm install moment --save
<p>发表时间:{{news.add_time | convertDate}}</p>
// main.js
// Moment:引入moment
import Moment from 'moment';
// 定义成全局组件或过滤器
Vue.filter('convertDate', function(value){
	return Moment(value).format('YYYY-MM-DD');
});

图片懒加载

懒加载:https://mint-ui.github.io/docs/#/zh-cn2/lazyload

<!-- 懒加载 -->
<img v-lazy="img.img_url">
<style>
/*图片懒加载的样式*/
image[lazy=loading] {
  width: 40px;
  height: 300px;
  margin: auto;
</style>     

缩略图、预览

预览: https://github.com/Ls1231/vue-preview

安装:

npm i vue-preview -S
<ul>
    <li v-for="(img,index) in imgs" :key="index">
        <img :src="img.src" height="100" @click="$preview.open(index, imgs)">
    </li>
</ul>
<script>
	// 缩略图
    this.$ajax.get('getthumimages/' + pid)
    .then(res=>{
        this.imgs = res.data.message;
        this.imgs.forEach((ele)=>{
            ele.w = 300;
            ele.h = 200; // 缩率图显示的高
        })
    })
    .catch(err=>{
        console.log(err)
    });
</script>

main.js

//VuePreview:引入vue-preview
import VuePreview from 'vue-preview'
Vue.use(VuePreview);

上拉加载更多

loadmore:https://mint-ui.github.io/docs/#/zh-cn/loadmore

<mt-loadmore
             :bottom-method="loadBottom"
             :bottom-all-loaded="allLoaded"
             :auto-fill="isAutoFill"
             ref="loadmore">	<!-- 上拉完毕调用该元素的onBottomLoaded函数 -->      
</mt-loadmore>
<script>
export default(){
    data(){
        return {
            allLoaded:false,  // 是否禁止出发上拉函数,false不禁止
            isAutoFill:false, // 是否自动触发上拉函数
        }
    },
    methods:{
        loadBottom(){
            console.log('上拉触发了');
            // 通知上拉操作已经完结
            this.$refs.loadmore.onBottomLoaded();
        }
    }
}
</script>

文件上传

app.js

'use strict';
const express = require('express');
const expressArtTemplate = require('express-art-template');
const app = express();
const formidable = require('formidable');
const router = express.Router();
const path = require('path');
// 配置模板引擎
app.engine('html', expressArtTemplate);
// express查找的时候也需要后缀名,
app.set('view options', {
    debug: process.env.NODE_ENV !== 'production',
    extname: '.html', // 自动补充后缀名的字符串
});
// 告知express使用该引擎
app.set('view engine', 'html');
router.get('/', (req, res, next) => {
     res.render('index');
});
router.post('/upload', (req, res, next) => {
    var form = new formidable.IncomingForm();
    // 为了能更好的保存文件在本地服务器目录
    form.uploadDir = path.join(__dirname,'files');
    // 解析请求,files里面是上传的文件
    form.parse(req, function(err, fields, files) {
        if(err) next(err);
        console.log('上传文件完毕')
    });
})
app.use(router);
// 返回jquery
app.use('/node_modules',express.static('./node_modules'));
// 监听端口
app.listen(8000, () => {
    console.log('服务器启动了');
})

同步上传:

<!-- 同步上传文件必须写上 enctype="multipart/form-data" -->
<form enctype="multipart/form-data" action="/upload" method="post">
     <input type="file" name="file" id="file">
     <input type="submit" name="" value="提交">
</form> 

异步上传:

<form>
     <input type="file" name="" id="file">
     <input type="submit" name="" value="提交">
</form>
<!-- 异步操作,原生 -->
<script type="text/javascript">
         document.querySelector('form').onsubmit = function(e){
         	e.preventDefault(); // 取消默认事件
            // 错误代码的出现会导致return false不执行,不太好调试程序
             var formData = new FormData();
             // 第一个参数key和表单中的name的值是一个意思
             // 第二个参数是文件的数据对象
             formData.append('myFile',document.getElementById('file').files[0])
             var xhr = new XMLHttpRequest();
             xhr.open('post','/upload');
             xhr.onreadystatechange = function(){
                 if(xhr.readyState == 4 && xhr.status === 200){
                     alert('成功');
                 }
             }
             xhr.send(formData);            
             // return false; // 取消默认事件
         }
</script>      

jquery上传:

<form>
       <input type="file" name="" id="file">
       <input type="submit" name="" value="提交">
</form>
<script type="text/javascript" src="/node_modules/jquery/dist/jquery.js"></script>
<script type="text/javascript">
  $('form').on('submit', function(e){
      var formData = new FormData();
      formData.append('myFile',document.getElementById('file').files[0]);
      e.preventDefault();
      // error:Illegal invocation, jquery默认头是content-type: www-url...键值对,改为data:'a=b',不报错
      $.ajax({  
          url: '/upload',
          type: 'post',
          data: formData, // 当传递formData的时候,默认将该对象转换成键值对字符串,这是不合理的
          // jquery上传文件必须要以下两个属性
          contentType: false, // 不需要头
          processData: false, // 不转换数据
          success: function(){
              console.log('ok');
          }
      })
  })
</script>

打包

提取css

安装:

npm install --save-dev extract-text-webpack-plugin

使用:

const version = 'v1.1.1';
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
    output: {
        path: path.join(__dirname, 'dist_css'),
        filename: 'build.js',
    },
    module:{
        loaders:[
            {
            	test: /\.css$/,
                // loader: 'style-loader!css-loader!autoprefixer-loader'
                // 打包提取css
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: "css-loader!autoprefixer-loader"
                })
        	}
        ]
    },
   plugins: [
        // 提取css插件,设置名称
        new ExtractTextPlugin("styles.css"),
    ]
} 

css+hash_1

path: path.join(__dirname, 'dist_hash'),
filename: '[chunkhash].js',
new ExtractTextPlugin("[contenthash].css"),   

提取第三方包

// 提取公共插件的依赖
const webpack = require('webpack');
// 再加一个入口
vendors: ['vue','vue-router','moment','axios','vue-preview'],
path: path.join(__dirname, 'dist_vendors'),
new webpack.optimize.CommonsChunkPlugin({
    //  manifest清单,用来记录使用者和第三方包的依赖关系
    names:['vendors','manifest']
}),       

CommonsChunkPlugin:https://webpack.js.org/plugins/commons-chunk-plugin/#root

提取第三方包2

filename: '[name].[chunkhash:6].js',
new ExtractTextPlugin("[name].[contenthash:6].css"),

uglifyjs-webpack-plugin

安装:

npm install uglifyjs-webpack-plugin --save-dev

问题:Cannot read property ‘compilation’ of undefined.

解决:package.json中改uglifyjs-webpack-plugin版本号为"uglifyjs-webpack-plugin": "^1.0.0"

webpack.config.js

dist_uglify
// 压缩混淆
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
path: path.join(__dirname, 'dist_uglify'),
// 压缩混淆代码
new UglifyJsPlugin(),

按需加载mint-ui

// mint-ui 按需引入 开始
import Header from 'mint-ui/lib/header';
import Switch from 'mint-ui/lib/switch';
import Swipe from 'mint-ui/lib/swipe';
import SwipeItem from 'mint-ui/lib/swipe-item';
import Lazyload from 'mint-ui/lib/lazyload';
import Loadmore from 'mint-ui/lib/loadmore';
import Indicator from 'mint-ui/lib/indicator';
import Button from 'mint-ui/lib/button';
Vue.component(Header.name, Header);
Vue.component(Switch.name, Switch);
Vue.component(Swipe.name, Swipe);
Vue.component(SwipeItem.name, SwipeItem);
Vue.component(Loadmore.name, Loadmore);
Vue.component(Button.name, Button);
Vue.use(Lazyload);
// mint-ui 按需引入 结束

webpack.config.js

path: path.join(__dirname, 'dist_mintui_partload'),    

划分目录

webpack.config.js

path: path.join(__dirname, 'dist_dir'),
// 设置资源路径的请求地址
// style.css  ->  /css/   assets/mui.ttf
// load的时候配置的name属性  assets/mui.ttf
publicPath:'/',   // 解决报错mui.tff的路径不对问题
filename: 'js/[name].[chunkhash:6].js',
name: 'assets/[name].[ext]'
new ExtractTextPlugin("css/[contenthash].css"),

分块路由懒加载

路由懒加载:https://router.vuejs.org/zh/guide/advanced/lazy-loading.html#%E6%8A%8A%E7%BB%84%E4%BB%B6%E6%8C%89%E7%BB%84%E5%88%86%E5%9D%97

webpack.config.js

path: path.join(__dirname, 'dist_lazy_load'),

main.js

// 引入自己的vue文件 开始  
import App from './app.vue';
// 按需加载
// const Foo = () => import('./Foo.vue')
// const Foo = resolve => require(['./Foo.vue'],resolve)  //只是个模板
const Home = r => require(['./components/home/home.vue'],r);
const Member = r => require(['./components/member/member.vue'],r);
const Shopcart = r => require(['./components/shopcart/shopcart.vue'],r);
const Search = r => require(['./components/search/search.vue'],r);
const NewsList = r => require(['./components/news/newsList.vue'],r);
const NewsDetail = r => require(['./components/news/newsDetail.vue'],r);
const PhotoShare = r => require(['./components/photo/photoShare.vue'],r);
const PhotoDetail = r => require(['./components/photo/photoDetail.vue'],r);
const GoodsList = r => require(['./components/goods/goodsList.vue'],r);
const GoodsDetail = r => require(['./components/goods/goodsDetail.vue'],r);
const GoodsComment = r => require(['./components/goods/goodsComment.vue'],r);

去除警告

Production Deployment: https://vuejs.org/v2/guide/deployment.html

path: path.join(__dirname, 'dist_production'),
new webpack.DefinePlugin({
    'process.env.NODE_ENV': JSON.stringify('production')
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值