创设npm插件vue-toast-m实例演习

3.4  webpack打包功能实现

(1) webpack准备

cnpm install webpack --save // 安装webpack

vue

cnpm install --save vue-template-compiler vue-loader

支持es6  http://babeljs.io/   安装 babel-preset-env后要建立 .babelrc文件写配置

cnpm install --save babel-core babel-loader babel-preset-env // babel-core是es6核心的文件,一定要有

(2) 新建webpack.config.js配置文件

var path = require('path');

module.exports = {
    entry: './src/lib/index.js',  // 入口
    output: {
        // path:'./dist',   // 指定输出路径
        path:path.join(__dirname,'./dist'),   // 必须是绝对路径
        filename: 'vue-toast-demo.js'   // 插件的名字
    },

    module:{  // module模块;解析一些webpack不认识的文件
        rules:[
            {
                test:/.vue$/,
                loader:'vue-loader'
            }
        ]
    },
    // js文件的合并,HTML的生成,插件等等
    plugins:[
        .....
    ]
};

(3) 打包命令

webpack  // 如果文件不叫webpack.config.js 可以使用--config参数传入路径 例:webpack --config ./webpackConfig/dev.config.js

如果成功会生成dist/vue-toast-demo.js文件,如果报错根据报错提示安装缺少的插件等

图片 1

比如上图就是缺少 vue-template-compiler插件,安装一下就行

图片 2

上图是缺少处理css样式的,vue-toast.vue是用sass处理样式
安装sass

cnpm install node-sass sass-loader --save  // sass-loader依赖于node-sass
cnpm install css-loader style-loader --save

(4)webpack.config.js详细配置

安装了各插件后还需配置

var path = require('path');

module.exports = {
    entry: './src/lib/index.js',  // 入口
    output: {
        // path:'./dist',   // 指定输出路径
        path:path.join(__dirname,'./dist'),   // 必须是绝对路径
        filename: 'vue-toast-demo.js',   // 插件的名字
        libraryTarget:'umd',   // 输出的文件格式,umd可适用各种规范(cmd/amd/commonjs...)
        library:'VueToastDemo'  // 输出的文件库的名字
    },

    module:{  // module模块;解析一些webpack不认识的文件
        // 放加载器
        rules:[
            {
                test:/.vue$/,   // 处理vue文件
                loader:'vue-loader',
                exclude:/node_modules/,
                options:{    // 解析vue文件中一些其他的语法
                    loaders:{
                        scss:'style-loader!css-loader!sass-loader'  // loader解析从右到左,先用sass-loader处理成css,再用css-loader进行处理,再用style-loader插入到HTML中
                    }
                }
            },
            {
                test:/.js$/,   // 处理js文件
                loader:'babel-loader',
                include:path.join(__dirname,'src'),  // 指定目录解析
                exclude:/node_modules/    // 过滤掉node_modules文件夹
            }
        ]
    },

    // js文件的合并,HTML的生成,插件等等
    plugins:[
        ......
    ]
};

main.js

//main.js这是项目的核心文件。全局的配置都在这个文件里面配置
import Vue from 'vue'
import App from './App.vue'
import router from './routes.js'

import './assets/styles/base.css'
//import './assets/sass/reset.sass'//报错暂时不用sass
Vue.config.debug = true;//开启错误提示

new Vue({
        router,
        el: '#appIndex',
        render: h => h(App)
})

源码

至此webpack打包大致的步骤已完成。 如果对配置文件或者目录结构有疑问,想看示例代码的可以带我的github: 上下载源码。

3.2  编写静态页面

vue-toast-demo/src文件夹下建立index.html静态页面

图片 3

新建项目

开始(确认已经安装node环境和npm包管理工具)

1、新建项目文件名为start_vuedemo

2、npm init -y初始化项目,我的win7系统,工程在d盘的vue_test_project文件夹下的名为start_vuedemo的工程文件夹

如图所示:

图片 4

在该工程下自动生成一个package.json文件。

图片

5.1 图片打包

让webpack看得懂图片格式,需要用到 url-loader ,命令安装:

npm install --save-dev url-loader

注意:这时候如果继续往下,到后面打包可能又会报错,因为url-loader是依赖于 file-loader 才运行的,我们命令安装:

npm install --save-dev file-loader

url-loader 还有另外一个功能,将小图片(可自设大小)自动转为base64,减少页面请求数,大赞的功能啊!在html和css写好背景图片后,

配置webpack.config.js:

var path = require('path')
var webpack = require('webpack')
    //分离css和js
var ExtractTextPlugin = require('extract-text-webpack-plugin')
    //生成html
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new ExtractTextPlugin("styles.css"),
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ],
    //组件loader
    module: {
        loaders: [
            // css转换
            {
                test: /.css$/,
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /.scss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            },
            //css背景图片转换
            {
                test: /.(png|jpg)$/,
                loader: 'url-loader?limit=8192'
            }
        ]
    }
}

运行打包后,打开index.html看看效果:

图片 5

5.2 html中的src图片

Webpack 不善于处理纯粹的 HTML, 要让webpack可以打包html中的src图片,需要用到html-withimg-loader。我们在index.html页面中添加一个src的img后命令安装:

npm install --save-dev html-withimg-loader

配置webpack.config.js:

var path = require('path')
var webpack = require('webpack')
    //分离css和js
var ExtractTextPlugin = require('extract-text-webpack-plugin')
    //生成html
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new ExtractTextPlugin("styles.css"),
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ],
    //组件loader
    module: {
        loaders: [
            // css转换
            {
                test: /.css$/,
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /.scss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            },
            //css背景图片转换
            {
                test: /.(png|jpg)$/,
                loader: 'url-loader?limit=8192'
            },
            //读取html,打包src图片
            {
                test: /.html$/,
                loader: "html-withimg-loader"
            }
        ]
    }
}

loader增加html-withimg-loader

然后在webpack.js里引入index.html:

require('./index.html')

运行打包,没报错即成功,打开dist文件夹里的html看看效果:

图片 6

可以看到src的图片已经被成功引入进来。

5.3 图片整理

我们仔细看看输入文件夹,图片 7

图片直接输出在dist文件夹,而且名称被重命名。当图片数量上去,非常不利于管理。我们在loader那完善:

{
    test: /.(png|jpg)$/,
    loader: 'url-loader?limit=8192&name=images/[name].[ext]'
},           

name字段指定了在输出目录(dist)新建一个images文件夹,来存放打包后的图片,名称是原图片命名。

图片 8

一、使用npm插件

import VueToast  from 'vue-toast-demo-cc'

Vue.use(VueToast)


this.$toast.show("hello,toast")
//or
this.$toast.show("hello,toast",{
  duration:3000
})
// or
this.$toast.show("hello,toast",function(){
    //to-do  
})

views文件放详情页面

运行

按上面步骤安装后,运行

webpack

即可打包,我们可以看到dist文件夹中生成了bundle.js,此时还未压缩,大小为3k。图片 9

2.1 多入口

我们看到打包后生成了一个js文件,那假如我们项目需求生成几个不同类别的js呢?例如当js文件数量多,就模块化打包后按需加载。

例如:webpack.js和webpack2.js要作为一个模块,而index.js和index2.js要作为另一个模块。这时entry和output就要换一种写法了:

配置webpack.config.js:

var path = require('path')
var webpack = require('webpack')
module.exports = {
  // 多入口
  entry: {
        name1: ['./src/webpack','./src/webpack2'],
        name2: ['./src/index','./src/index2']
  },
  // 输出
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js' //可重命名
  }
}

运行打包后可以在dist里看到两个name.js

图片 10

js模块化分离打包成功。

2.2 UglifyJsPlugin

UglifyJsPlugin是webpack自带的核心插件,无需安装,无需声明require直接使用。它运行UglifyJs来压缩输入文件。

配置webpack.config.js,增加plugins项,里面放置插件

var path = require('path')
var webpack = require('webpack')
module.exports = {
  // bundle入口
  entry: ['./src/webpack'],
  // bundle输出
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js' //可重命名
  },
  //插件
  plugins: [
        //压缩
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
   ]
}

更改配置后,运行webpack打包,可以看到大小1k(实际是500多字节),压小了不少。

图片 11

3.5  打包后测试

src/index.html修改使用

cnpm install vue --save  // 安装vue

<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript" src="../dist/vue-toast-demo.js"></script>

<div id="app" class="text-center">
    <h2>vue-toast for mibile</h2>
    <div class="form-group row">
        <a class="btn btn-primary" href="javascript:;" @click="toast">默认toast</a>
    </div>
    <div class="form-group row">
        <a class="btn btn-info" href="javascript:;" @click="toast2">5秒后关闭toast</a>
    </div>
    <div class="form-group row">
        <a class="btn btn-success" href="javascript:;" @click="toast3">关闭toast后,执行回调</a>
    </div>
</div>
<script type="text/javascript">
    new Vue({
        el:"#app",
        methods:{
            toast:function(){
                this.$toast.show("当前点击了标签");
            },
            toast2:function(){
                this.$toast.show("当前点击了标签",{
                    duration:5000
                });
            },
            toast3:function(){
                this.$toast.show("当前点击了标签",function(){
                    alert("这里是回掉函数")
                });
            }
        }
    })
</script>

执行webpack打包命令后运行index.html

图片 12

新建一个index.html

在根目录下新建一个index.html,这个index.html也即是首页入口文件,代码如下:

代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="appIndex">

        </div>
    <script src="./dist/build.js"></script>
    </body>
</html>

说明下:引用的这个js是通过webpack指令生成的dist/build.js文件。这儿先引用吧

什么是webpack?

Webpack 是当下最热门的前端资源模块化管理和打包工具。它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分隔,等到实际需要的时候再异步加载。通过 loader 的转换,任何形式的资源都可以视作模块,比如 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 SASS 等。

webpack是基于node.js环境的前端自动化打包工具,本文默认你已有一定使用node和npm安装的基础。

3.1  新建vue-toast-demo文件夹

cd vue-toast-demo   // 进入文件夹
npm init  // 初始化npm,生成package.json

输入npm init之后生成package.json

图片 13

package.json

{
  "name": "vue-toast-demo",
  "version": "1.0.0",   // 版本
  "description": "a toast plugin for mobile",
  "main": "index.js",   // 入口文件
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "repository": {   // github
    "type": "git",
    "url": "git https://github.com/ccyinghua/vue-toast-demo.git"
  },
  "keywords": [    // 关键词
    "toast",
    "vue-toast"
  ],
  "author": "ccyinghua",  // 作者
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/ccyinghua/vue-toast-demo/issues"
  },
  "homepage": "https://github.com/ccyinghua/vue-toast-demo#readme"
}

about.vue

//about.vue
<template>
    <div>about</div>
</template>

Babel

Babel 是一款转码编译器,可以很方便地将 ES6、ES7 等当前浏览器不兼容的 JavaScript 新特性转码为 ES5 等当前浏览器普遍兼容的代码。将两者结合起来可以很方便地在项目中一边使用 ES6 编写代码,一边自动生成 ES5 代码。

Babel有不同的插件,可以按需安装:

安装相关组件:

//安装加载器 babel-loader 和 Babel 的 API 代码 babel-core
npm install --save-dev babel-loader babel-core

安装 ES2015(ES6)的代码,用于转码
npm install babel-preset-es2015 --save-dev

//用于转换一些 ES6 的新 API,如 Generator,Promise 等
npm install --save babel-polyfill

配置webpack.config.js:

var path = require('path')
var webpack = require('webpack')
    //分离css和js
var ExtractTextPlugin = require('extract-text-webpack-plugin')
    //生成html
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    // bundle入口
    entry: [
        './node_modules/webpack-dev-server/client?http://localhost:8080',
        './node_modules/webpack/hot/dev-server',
        './node_modules/babel-polyfill',
        './src/webpack',
        './src/index'
    ],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        // new webpack.optimize.UglifyJsPlugin({
        //     compress: {
        //         warnings: false
        //     }
        // }),
        //分离css和js
        new ExtractTextPlugin("styles.css"),
        //生成html页面
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        //热加载
        new webpack.HotModuleReplacementPlugin()
    ],
    //组件loader
    module: {
        loaders: [
            // css转换
            {
                test: /.css$/,
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /.scss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            },
            //css背景图片转换
            {
                test: /.(png|jpg)$/,
                loader: 'url-loader?limit=8192&name=images/[name].[ext]'
            },
            //读取html,打包src图片
            {
                test: /.html$/,
                loader: "html-withimg-loader"
            },
            //编译es6,转化为es5
            {
                test: /.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel-loader', 
                query: {
                    presets: ['es2015']
                }
            }
        ]
    },
    devServer: {
        contentBase: './dist',
        hot: true
    }
}

entry入口那里增加了babel-polyfill,loader增加babel-loader。由于要验证打包后的js是否已编译转为es5,所以这里注释代码压缩的插件。

在index.js里任意输入一个es6语法的语句:

图片 14

然后再打开打包后的bundle.js文件,拉到最下面,可以发现该es6语句已被转为es5语法输出:

图片 15

编译转码成功。

三、npm 插件制作

reset.scss

$redColor:#f00;
h2{
    color:$redColor;
}

前言

本文是基于我厂基友的Webpack学习系列(一)初学者使用教程 这篇文章做构建。可能基友的文章是基于Mac环境,我是windows环境,在学习时遇到了很多坑,询问基友,他让我搞个基于windows环境的,我想了想,正好这几天需求不多,webpack3.0也来了,那就干吧!

3.3  插件功能实现

vue-toast-demo/src/lib/vue-toast.vue组件页面,将静态文件搬到vue文件中

<template>
    <section class="toast-container">
        <div class="toast" v-bind:class="[visible?'fade-in':'fade-out']">
            {{message}}
        </div>
    </section>
</template>

<script>
export default{
    data(){
        return {
            message:'',
            visible:false
        }
    }
}
</script>

<style scoped lang="scss">
    ......
</style>

src/lib/index.js入口文件

// 入口文件
import ToastComponent from './vue-toast.vue'

let Toast = {}
Toast.install = function(Vue,options){   // 必须定义一个install方法,才可以在使用时Vue.use()
    // 默认配置
    var opt = {
        duration:3000
    }

    // 用户配置覆盖默认配置
    for(var key in options){
        opt[key] = options[key];
    }

    // 在vue的原型上面拓展一个$toast函数
    Vue.prototype.$toast = function(message,option){
        let callback = '';
        // 配置覆盖,设置局部配置
        if(typeof option == 'object'){
            for(var key in option){
                opt[key] = option[key];
            }
        }else if(typeof option == 'function'){
            callback = option;
        }

        // 用Vue.extend()继承ToastComponent组件,构成一个ToastController实例
        const ToastController = Vue.extend(ToastComponent);

        //new ToastController()相当于一个新的Vue对象
        //这个对象挂载到空的div里面,类似于vue组件中 var vm = new Vue({ data:{} ... }).$mount("#app")功能
        var instance = new ToastController().$mount(document.createElement("div"));

        instance.message = message;
        instance.visible = true;

        document.body.appendChild(instance.$el);

        setTimeout(()=>{
            instance.visible = false;
            setTimeout(()=>{
                document.body.removeChild(instance.$el);
                callback && callback();
            },500)
        }, opt.duration)
    };

    // Vue.prototype.$toast['show'] = function(message,option){
    //      Vue.prototype.$toast(message,option);
    // }
    // Vue.prototype.$toast['success'] = function(message,option){
    //      Vue.prototype.$toast(message,option);
    // }
    // Vue.prototype.$toast['info'] = function(message,option){
    //      Vue.prototype.$toast(message,option);
    // }
    // Vue.prototype.$toast['error'] = function(message,option){
    //      Vue.prototype.$toast(message,option);
    // }

    // 简化上面代码
    ['show','success','info','error'].forEach(function(type){
        Vue.prototype.$toast[type] = function(message,option){
            return Vue.prototype.$toast(message,option);
        }
    });

}

// if(window.Vue){
//     Vue.use(Toast);
// }

if(typeof window !== 'undefined' && window.Vue){
    window.Vue.use(Toast);
}

// 导出
export default Toast;

编辑项目目录以及添加代码

问题

至此webpack打包大致的步骤已完成。在行文过程中,发现了几个问题不得其解,网上谷歌搜索也搜不出个所以然,故在这里把问题抛出,希望知道的大神不吝赐教。

一:热加载那里,我发现假如引用的是css文件,修改内容热加载有效果,但引用scss文件热加载就失效了,如何让引用scss文件也能实现热加载呢?

二:html-withimg-loader和raw-loader的区别是什么呢?网上的解释都说是对html解析成字符串,让js读懂。网有些文章,热加载用的loader是raw-loader,但我发现用html-withimg-loader也能跑起来。

制作npm插件vue-toast-m实例练习(消息弹窗)

运行项目

执行指令:webpack

图片 16

执行webpack-dev-server:

 

webpack-dev-server

 

图片 17

 

 浏览器打开生成的链接:

效果如图所示:

图片 18

 

 到这儿项目就运行起来了。

调试

到这里,基础页面已经成型,接下来就是开发了,开发需要调试。那么我们怎么调试这个页面呢?

如果每次改一次页面,就要打包一次,严重降低效率。运行命令:

webpack --watch

开着这个命令终端,我们修改的html,css(sass),js等静态文件都可以通过刷新html页面直接看到效果。

看到这,有同学说我F5键已抠,懒得每次都要按刷新怎么办?

这时候热加载(HMR)可以帮到你,首先,跑起一个服务。

四、npm插件发布

npm官网:  注册自己的用户,记住注册时的用户名密码。接下来就可以执行命令。

npm adduser   // 添加用户:输入用户名密码和邮箱

npm whoami  // 验证当前用户是谁,验证是不是之前添加的用户

npm publish  // 发布

package.json中name是插件的名字,首先要在npm搜索一下是不是有同名字的插件,如果有是不能以这个名字发布的;version是插件版本,如果改动了项目,需要修改一下版本号再进行npm publish发布。

图片 19

因为插件名字在npm已经有了,所以把name改为vue-toast-demo-cc再发布。 发布成功:

图片 20

 

css样式添加

plugins

顾名思义,Plugins 就是webpack的插件。loader只能对静态文件做处理,而Plugins 不处理单个文件,而是作用于整个构建流程。上面提到的UglifyJsPlugin,也是插件的一种。

4.1 分离CSS和JavaScript ——Extract Text Plugin

进行到这里,我们会发现,打包之后的css和js都集合在一起,那到时候引入到页面上,是放到头部,还是尾部呢?显然都是不可取的:无论放头部和尾部,js都会阻塞页面渲染。而插件 Extract Text Plugin 可以帮助我们分离css和js。

命令安装:

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

配置webpack.config.js

头部增加Extract Text Plugin插件引入,在plugins那里new一个你想输出的样式文件,最后在loader那增加插件写法。

var path = require('path')
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new ExtractTextPlugin("styles.css")
    ],
    //组件loader
    module: {
        loaders: [ 
            // css转换
            {
                test: /.css$/, 
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /.scss$/,
                loader: ExtractTextPlugin.extract('style-loader', 'css-loader', 'sass-loader')
            }
        ]
    }
}

注意:没错,这里又有坑。

先运行打包一下:图片 21

日常报错。所幸日志里面有提醒我们:你的代码老掉牙了,换种写法吧!

来,把sass转换那部分用新的格式重写一遍:

// sass转换 
{
  test: /.scss$/,
  loader: ExtractTextPlugin.extract({
          fallback:'style-loader', 
          use:['css-loader','sass-loader']
  })
}

运行打包,终于成功,看到dist文件夹里生成了styles.css和bundle.js

图片 22

4.2 生成html

经历各种报错,终于完成编译css和js。接下来我们利用插件html-webpack-plugin来生成集成html

命令安装:

npm install --save-dev html-webpack-plugin

配置webpack.config.js,添加插件方法和 4.1 一样

var path = require('path')
var webpack = require('webpack')
//分离css和js
var ExtractTextPlugin = require('extract-text-webpack-plugin')
//生成html
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new ExtractTextPlugin("styles.css"),
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ],
    //组件loader
    module: {
        loaders: [
            // css转换
            {
                test: /.css$/,
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /.scss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            }
        ]
    }
}

运行打包,可以看到再dist文件夹里生成了一个html文件,webpack自动把css和js分别帮我们插入到头部和尾部,这一点很智能。

图片 23

二、项目结构

npm插件原地址:

webpack官网: 

项目github地址: 

|-- src
    |-- lib
        |-- index.js  --// 入口文件
        |-- vue-toast.vue
    |-- index.html  -- // 静态文件
|-- .babelrc
|-- package.json
|-- webpack.config.js --// 配置文件

commponents下的header.vue

<template>
    <div>
        <h1>共同header</h1>
        <img src="../assetslogo.png">
    </div>
</template>
<style>
    @import '../assets/sass/common.scss'
</style>

注意:这儿自己手动放一张logo图片到images文件夹下面。

安装

1.1 webpack安装

首先新建一个练习文件夹demo,在文件中打开命令终端,输入下列指令即可安装webpack

//全局安装

npm install -g webpack

//安装到项目文件夹

npm install --save-dev webpack

安装完之后,demo里会多一个node_modules文件夹。

接下来输入

npm init

会自动创建package.json文件。安装的时候一路回车即可,需要修改后面再进入package.json文件编辑。

package.json文件是webpack的骨架,在里面可以看到各个关键节点,设置快捷命令等。

1.2 文件夹部署

安装好上面的东西,我们开始往demo文件夹塞东西,新建distsrc文件夹、webpack.config.js配置文件来模拟开发环境。最终目录如下:

demo                      //webpack的模拟开发文件夹
   | - webpack.config.js  //配置webpack出入口、插件、loader
   | - node_modules
   | - dist               //打包输出文件夹
   | - src                //开发资源文件夹
     | - webpack.js     //配置webpack引入资源
     | - index.html     /*   基础html文件
     | - index.js            基础js文件
     | - index.css           基础css文件
     | - index.scss          基础scss文件            
     | - images              基础图片文件夹   */
         | - img1.png
         | - img2.png

1.3 配置webpack.config.js

var path = require('path')
var webpack = require('webpack')
module.exports = {
  // bundle入口
  entry: ['./src/webpack'],
  // bundle输出
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js' //可重命名
  }
}

base.css

h1{
    color: #999;
}

loader

Webpack 本身只能理解、处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。通过使用不同的loader,webpack通过调用外部的脚本或工具可以对各种各样的格式的文件进行处理。

总结:Webpack 只能看懂JavaScript ,对于其他静态文件,需要用loader帮助理解转换。

Loaders的配置选项包括以下几方面:

  • test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须)
  • loader:loader的名称(必须)
  • include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
  • query:为loaders提供额外的设置选项(可选)

介绍完毕,撸起来!

3.1 编译CSS

命令安装 css-loader

npm install --save-dev style-loader css-loader

关于loaders的放置顺序:loader解析是从右向左,css-loader用于解析,而style-loader则将解析后的样式嵌入js代码。

配置webpack.config.js,增加module项,里面放置css-loader

var path = require('path')
var webpack = require('webpack')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ],
    //组件loader
    module: {
    loaders: [{
       // css转换
       test: /.css$/,
       loaders: ['style-loader', 'css-loader']
    }]
  }
}

配置webpack.js文件,引入index.css

require('./index.css') 

创设npm插件vue-toast-m实例演习。运行 webpack 打包,无报错即编译成功,可以在bundle.js文件里看到压缩进去的css文件。

注意:这里有个小坑,网上很多资料都说可以省略"-loader",即:

loaders: [{
       // css转换
       test: /.css$/,
       loaders: ['style', 'css']
}]

在windows环境我们按这种写法打包一下,会发现报错:

图片 24

可以看到,里面提到不再允许省略"-loader"的写法。所以当我们写loader名称时不要简写。

3.2 编译sass(scss)

命令安装 sass-loader

npm install --save-dev style-loader sass-loader

发现有飘红信息:图片 25

缺少 node-sass 依赖,我们再敲一行命令装上去就可以了:

npm install --save-dev style-loader node-sass

然后 npm list 命令看看有没有安装成功,后面带别的名称即可查其他分支。如sass-loader

npm list node-sass

配置webpack.config.js,增加sass-loader

var path = require('path')
var webpack = require('webpack')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ],
    //组件loader
    module: {
        loaders: [ 
            // css转换
            {
                test: /.css$/, 
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /.scss$/,
                loaders: ['style-loader', 'css-loader', 'sass-loader']
            }
        ]
    }
}

配置webpack.js文件,引入index.scss

require('./index.css') 
require('./index.scss') 

运行 webpack ,没报错就是编译sass成功了。编译less同理,不赘述。

项目结构

如图所示:

图片 26

结构说明:

dist文件是后面执行webpack指令生产的,不用管;

webpack.config.js 配置文件,本身也是一个标准的Commonjs规范的模块;

routes.js文件放路由配置文件;

index.html首页入口文件

App.vue是项目入口文件。

main.js这是项目的核心文件。全局的配置都在这个文件里面配置。

commponents目录里面放了公共组件header文件。

views文件放详情页面;

服务

6.1 轻量的node.js express服务器——Webpack-dev-server

webpack可以跑起一个微型服务器,直接作用于资源文件,方便我们开发调试。其中热加载是一个非常实用的功能。命令安装Webpack-dev-server

npm install --save-dev webpack-dev-server

配置webpack.config.js:

var path = require('path')
var webpack = require('webpack')
    //分离css和js
var ExtractTextPlugin = require('extract-text-webpack-plugin')
    //生成html
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    // bundle入口
    entry:  [
        './node_modules/webpack-dev-server/client?http://localhost:8080',
        './node_modules/webpack/hot/dev-server',
        './src/webpack'
    ],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename:  'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new ExtractTextPlugin("styles.css"),
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        new webpack.HotModuleReplacementPlugin()
    ],
    //组件loader
    module: {
        loaders: [
            // css转换
            {
                test: /.css$/,
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /.scss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            },
            //css背景图片转换
            {
                test: /.(png|jpg)$/,
                loader: 'url-loader?limit=8192'
            }
        ]
    },
    devServer: {
        contentBase: './dist',
        hot: true
    }
}

增加两个入口,用于关联服务器;devServer里面的contentBase指向你的输出文件夹dist(或其他命名),hot表示是否开启热加载。

可以从入口看出项目服务访问地址是:http://localhost:8080。

跑服务的命令是:

webpack-dev-server --config webpack.config.js

每次都这么输入太累赘,可以在package.json里配置命令:

"scripts": {
    "dev": "webpack-dev-server --config webpack.config.js"
},

这样每次跑服务,直接:

npm run dev

就可以了,当然你也可以自由更改端口号,例如把8080改为8888:

"scripts": {
    "dev": "webpack-dev-server --host localhost --port 8888 --config webpack.config.js"
 },

运行服务命名,在浏览器输入相应端口号,就可以看到运行于webpack服务的页面了

图片 27

6.2 热加载(HMR)

终于到重点了。跑起来的8080服务页面,目标调试需要刷新页面才能生效,但只要我们使用HMR,只要代码有改动,无需刷新页面,浏览器会自动更新。

在上文的图片模块中(5.2),已引入了html-withimg-loader ——可以将html转为字符串的loader,在这就省略引入解析html-loader的步骤。

配置webpack.config.js:

var path = require('path')
var webpack = require('webpack')
    //分离css和js
var ExtractTextPlugin = require('extract-text-webpack-plugin')
    //生成html
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    // bundle入口
    entry: [
        './node_modules/webpack-dev-server/client?http://localhost:8080',
        './node_modules/webpack/hot/dev-server',
        './src/webpack'
    ],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        //分离css和js
        new ExtractTextPlugin("styles.css"),
        //生成html页面
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        //热加载
        new webpack.HotModuleReplacementPlugin()
    ],
    //组件loader
    module: {
        loaders: [
            // css转换
            {
                test: /.css$/,
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /.scss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            },
            //css背景图片转换
            {
                test: /.(png|jpg)$/,
                loader: 'url-loader?limit=8192'
            }, 
            //读取html,热加载
            {
                test: /.html$/,
                loader: "html-withimg-loader" 
            }
        ]
    },
    devServer: {
        contentBase: './dist',
        hot: true
    }
}

在plugins增加热加载插件;loader增加raw-loader,正则匹配html。

运行:

npm run dev

现在你随意修改页面内容,会发现不用手动刷新浏览器就自动更新了你所更改的内容。

安装项目依赖

3、npm install --save vue默认安装最新版vue

4、npm install --save-dev webpack webpack-dev-server 安装webpack,webpack-dev-server(是一个小型的Node.js Express服务器)

注:npm install 在安装 npm 包时,有两种命令参数可以把它们的信息写入 package.json 文件,一个是npm install --save另一个是 npm install --save-dev,他们表面上的区别是--save 会把依赖包名称添加到 package.json 文件 dependencies 键下,--save-dev 则添加到 package.json 文件 devDependencies 键下,
--save-dev 是你开发时候依赖的东西,--save 是你发布之后还依赖的东西。

如下所示,在package.json文件中:

"dependencies": {
    "vue": "^2.4.2"
  },
  "devDependencies": {
    "webpack": "^3.4.1",
    "webpack-dev-server": "^2.6.1"
  }

5、npm install --save-dev babel-core babel-loader babel-preset-es2015安装babel,babel的作用是将es6的语法编译成浏览器认识的语法es5

这时,package.json部分增加代码如下:

"dependencies": {
    "vue": "^2.4.2"
  },
  "devDependencies": {
    "babel-core": "^6.25.0",
    "babel-loader": "^7.1.1",
    "babel-preset-es2015": "^6.24.1",
    "webpack": "^3.4.1",
    "webpack-dev-server": "^2.6.1"
  }

6、npm install --save-dev vue-loader vue-template-compiler 用来解析vue的组件,.vue后缀的文件

7、npm install --save-dev css-loader style-loader 用来解析css

拓展:css-loader 和 style-loader,二者处理的任务不同,css-loader使你能够使用类似@import 和 url(…)的方法实现 require()的功能,style-loader将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。

8、npm install --save-dev url-loader file-loader 用于打包文件和图片

9、npm install --save-dev sass-loader node-sass 用于编译sass

10、npm install --save-dev vue-router 安装路由

App.vue

在新建项目入口文件App.vue,当然也是在src文件夹下,代码如下:

<!--App.vue是项目入口文件。-->
<template>
    <div id="app">
        <header-tab></header-tab>
        <h2>{{msg}}</h2>
        <div class="nav-box">
            <p class="nav-list">
                <router-link class="nav-item" to="/">首页</router-link>
                <router-link class="nav-item" to="/about">关于</router-link>
            </p>
        </div>
        <div>
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
import HeaderTab from './components/header.vue';
export default {
  name: 'app',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  components:{
    HeaderTab
  }
}
</script>

<style lang="scss">
    $redColor:#f00;
    h2{
        color:$redColor;
    }
    #app {
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
    }
    h1, h2 {
        font-weight: normal;
    }
    ul {
        list-style-type: none;
        padding: 0;
    }
    li {
        text-align: left;
        margin: 0 10px;
    }
    a {
        color: #42b983;
    }
</style>

 参考地址

https://segmentfault.com/a/1190000008602934

其中参考地址里面是有一些问题的,比如sass的文件后缀为.sass的文件需要严格按照该后缀的格式写样式,不能有{}与;等。再一个就是在main.js中引入.sass文件是会报错的,最后的解决办法就是放到比如header.vue这样的vue文件中,以如下方法引入:

<style>
    @import '../assets/sass/reset.scss'
</style>

 

webpack.config.js

在项目根路径下新建webpack.config.js 配置文件,本身也是一个标准的Commonjs规范的模块;

var path = require('path')
var webpack = require('webpack')

module.exports = {
    entry: './src/main.js',//值可以是字符串、数组或对象
    output: {
        path: path.resolve(__dirname, './dist'),//Webpack结果存储
        publicPath: '/dist/',//懵懂,懵逼,//然而“publicPath”项则被许多Webpack的插件用于在生产模式和开发模式下下更新内嵌到css、html,img文件里的url值
        filename: 'build.js'
    },
    module: {
        rules: [
            {
                test: /.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                    }
                    // other vue-loader options go here
                }
            },
            {
                test: /.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /.(png|jpg|gif|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]?[hash]'
                }
            }
            //自己加的
            ,
            {
                test: /.css$/,
                loader: "style-loader!css-loader"
            }
            ,
            {
                test: /.scss$/,
                loader: "style-loader!css-loader!sass-loader!"
            }
        ]
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    },
    devServer: {//webpack-dev-server配置
        historyApiFallback: true,//不跳转
        noInfo: true,
        inline: true//实时刷新
    },
    performance: {
        hints: false
    },
    devtool: '#eval-source-map'
}

if (process.env.NODE_ENV === 'production') {
    module.exports.devtool = '#source-map'
    // http://vue-loader.vuejs.org/en/workflow/production.html
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        new webpack.optimize.UglifyJsPlugin({
            sourceMap: true,
            compress: {
                warnings: false
            }
        }),
        new webpack.LoaderOptionsPlugin({
            minimize: true
        })
    ])
}

解释:

test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须) 。
loader:loader的名称(必须) 。
include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选)。

home.vue

<template>
    <div>
        <ol>
            <li v-for="todo in todos">
                {{ todo.text }}
            </li>
        </ol>
        <button @click="eClick()">事件</button>
    </div>
</template>

<script>
export default {
  name: 'indexP',
  data () {
    return {
       todos: [
          { text: '首页第一段文本' },
          { text: '首页第二段文本' },
          { text: '首页第三段文本' }
        ]
    }
  },
  methods:{
    eClick(){
        console.log(9999);
    }
  }
}
</script>
<style scoped>
    ol{width:200px;margin:20px auto;}
</style>

routes.js

下面的内容没有特殊说明,都是在根路径下新建的一个src文件夹,然后内容放置于src文件夹下面。

routes.js文件放路由配置文件,代码如下:

// 引用模板
import Vue from 'vue';
import Router from 'vue-router';
import indexPage from './components/header.vue'
import homePage from './views/home.vue'
import aboutPage from './views/about.vue'

Vue.use(Router)

export default new Router({
    routes:[
        {
            path:'/',
            component:homePage
        },
        {
            path:'/about',
            component:aboutPage
        }
    ]
})

本文由上海时时乐走势图发布于web前端,转载请注明出处:创设npm插件vue-toast-m实例演习

您可能还会对下面的文章感兴趣: