webpack4+vue2+nifty2.9构建单页应用

Nifty是一个基于Bootstrap的后台管理模版,不过需要付费购买,如果想用免费开源的可以考虑AdminLTE。

1.初始化,安装依赖
# 初始化项目
mkdir webpack-vue-nifty && cd webpack-vue-nifty && npm init -y

# 基础依赖
npm install --save-dev webpack \
webpack-cli \
style-loader \
css-loader \
file-loader \
url-loader \
html-loader \
html-webpack-plugin \
mini-css-extract-plugin

# 运行时依赖
npm install --save vue jquery [email protected] vue-router

# 打包构建时时依赖
npm install --save-dev vue-loader \
vue-style-loader \
vue-template-compiler \
vue-hot-reload-api \
babel \
[email protected] \
babel-core \
babel-plugin-transform-runtime \
babel-plugin-syntax-dynamic-import \
babel-preset-es2015 \
babel-runtime

# 开发调试
npm i --save-dev webpack-dev-server
2.补充npm脚本

package.json

{
  "name": "webpack-vue-nifty",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "dev": "webpack-dev-server --inline --progress --compress --hot --open --history-api-fallback --config webpack.config.js --host 127.0.0.1 --port 8888"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel": "^6.23.0",
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-runtime": "^6.26.0",
    "css-loader": "^1.0.0",
    "file-loader": "^2.0.0",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.4.3",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.1",
    "vue-hot-reload-api": "^2.3.1",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.9"
  },
  "dependencies": {
    "bootstrap": "^3.3.7",
    "jquery": "^3.3.1",
    "vue": "^2.5.17",
    "vue-router": "^3.0.1"
  }
}

3.完善webpack配置

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
    mode: 'production',
    entry: {
        index: './src/index.js'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/[name].[hash:8].js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['es2015'],
                        plugins: ['transform-runtime', 'syntax-dynamic-import']
                    }
                }
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            publicPath: '../'  // 特别重要,否则css文件打包后其中引用的图片文件不正确
                        }
                    },
                    "css-loader"
                ]
            },
            {
                test: /\.html$/,
                use: {
                    loader: 'html-loader'
                }
            },
            {
                test: /\.(png|jpg|gif|jpeg|svg|eot|woff|woff2|ttf)$/,
                use:[
                    {
                        loader: "url-loader",
                        options: {
                            name: "img/[name].[hash:5].[ext]",
                            limit: 1024, // size <= 1kib
                            // outputPath: "img",
                            publicPath: "../"
                        }
                    }
                ]
            },
            {
                test: /\.vue$/,
                use: 'vue-loader'
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "css/[name].[hash:8].css",
        }),
        new HtmlWebpackPlugin(
            {
                template: './src/index.html',
                filename:'./index.html',
                hash: false,
                chunks: ['index']
            }
        ),
        new VueLoaderPlugin(),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            Vue: ['vue/dist/vue.esm.js', 'default'],
            VueRouter: ['vue-router/dist/vue-router.esm.js', 'default']
        })
    ],
    devServer: {
        contentBase: path.resolve(__dirname, "../dist/"),
        index:'./index.html'
    }
};
4.完善入口文件,配置路由

index.js

import App from './app.vue'

Vue.use(VueRouter);

const Container = () => import('./pages/container.vue');
const Home = () => import('./pages/home.vue');
const Setting = () => import('./pages/setting.vue');

const routes = [
    {
        path: '/',
        component: Container,
        children: [
            { path: '/home', component: Home },
            { path: '/setting', component: Setting }
        ]
    },
    { path: '/setting', component: Setting }
];

const router = new VueRouter({
    mode: 'history',
    routes: routes
});

new Vue({
    el: '#app',
    router: router,
    components: { App }
});

index.html




    
    
    Title


    

app.vue






5.引入Nifty

复制nifty中get-started中几个目录导src/nifty下,目录结构如下

$ tree -I node_modules -L 3
.
├── package-lock.json
├── package.json
├── src
│   ├── app.vue
│   ├── index.html
│   ├── index.js
│   ├── nifty
│   │   ├── css
│   │   ├── img
│   │   ├── js
│   │   ├── plugins
│   │   └── premium
│   └── pages
│       ├── home.vue
│       ├── main.vue
│       └── setting.vue
└── webpack.config.js

src/pages/container.vue






另外,的图片路径需要稍作调整,如果遇到不存在的图片,需要到nifty的demo目录寻找。

使用npm run dev打开页面调试,会报错Uncaught TypeError: Cannot read property 'setTimeout' of undefined,将nifty.min.js中以下内容稍作修改后一切正常。

修改前

a.timeoutId&&e.clearTimeout(a.timeoutId),a.timeoutId=e.setTimeout(function(){n.trigger(t.eventName)},t.delay)}

修改后

a.timeoutId&&function(e){e.clearTimeout(a.timeoutId)},a.timeoutId=function(e){e.setTimeout(function(){n.trigger(t.eventName)},t.delay)}}

参考 https://stackoverflow.com/questions/24338761/jquery-settimeout-cannot-read-property-preventdefault-of-undefined

到这里,webpack4+vue2+nifty构建的单页应用初步完成。

6.引入Ion Icons

Ionicons is a completely open-source icon set with 700+ icons crafted for web, iOS, Android, and desktop apps.

首先安装ionicons

npm i ionicons

然后在container.vue中引入及使用css




你可能感兴趣的:(webpack4+vue2+nifty2.9构建单页应用)