Table of Contents
这几天写了一个诗词网站的一个 demo。目的是练习 vue 以及 webpack。之所以选择诗词网站,一是手上有诗词的数据库(从一个诗词软件里拷贝过来的)。二是不算复杂,适合练手。下面回忆一下练习中碰到的问题。
文章最初分布在简书,时间为 2018.06.17 20:41 。
链接:https://www.jianshu.com/p/969f9529aa01
首先,是整体规划的问题
虽然是个小 demo,也许正因为是个小 demo ,所以没有详细规划,想到一个功能写一个功能,想到一个页面写一个页面。结果就是组件改了又改,束手束脚,后台 php 也是不停的更改。不过好歹是写出来了。差点忘了,先放一下目录结构。
./src/ |-- assets | |-- font | | |-- iconfont.eot | | |-- iconfont.svg | | |-- iconfont.ttf | | `-- iconfont.woff | |-- js | | |-- base.js | | `-- iconfont.js | `-- styles | |-- iconfont.css | `-- main.less |-- home.html |-- index.js |-- index.php `-- poem |-- article | |-- article.html | |-- article.js | `-- articlebody.vue |-- author.vue |-- authors | |-- authors.js | `-- styles | `-- authors.less |-- body.vue |-- footer.vue |-- header.vue |-- poem.vue |-- poems | |-- pages.vue | |-- poems.js | `-- poemsbody.vue `-- search |-- search.js `-- searchbody.vue
目录比较乱。assets 目录下包含 font、js、styles。其中 base.js
并未用到。首页的文件直接在 src 文件夹下,需要的组件在 poem 文件下。其余的页面也在 poem 文件夹下。除了首页,其他页面共用 article.html
模板。实际上可以都用首页的,因为结构是一样的。
组件调用有点混乱,主要是没有统一放到一个文件夹里,而是散落在各个页面文件夹里。以后的项目还是注意点好。
二、 vue 引入的问题。
一开始写的是:
import Vue from "vue"
结果报错了,因为这句话导入的并不是 vue.js
,而是vue.common.js
。将其改成下面的就好了。
import Vue from "vue/dist/vue.js"
于是问题又来了,之前的练习 TodoApp 里使用的就是第一句,为什么那里没有问题呢?查看了一下代码,原来 TodoApp 里入口文件使用的是 render,而不是 components 属性。至于 vue.js
和 vue.common.js
的不同可以查考下面的文章:
Vue 2.0 升(cai)级(keng)之旅
webpack+vue的匹配报错
三、 webpack 多页面问题
关于 webpack 多页面的问题,在写这个 demo 之前就已经百度了很多,但都没弄懂。所以,一开始写这个 demo 的时候就用了一个页面一个配置文件的方法,等到写完在慢慢折腾 webpack。下面就是折腾的结果:
const config = { …… entry: { index: './src/index.js', authors: './src/poem/authors/authors.js', poems: './src/poem/poems/poems.js', search: './src/poem/search/search.js', article: './src/poem/article/article.js' }, output: { filename: "js/[name].[chunkhash:8].js", path: path.resolve(__dirname,'dist') }, …… plugins: [ …… new HTMLPlugin({ template: './src/home.html', filename: './home.html', chunks: ['lib','index'] }), new HTMLPlugin({ template: './src/poem/article/article.html', filename: 'poems.html', chunks: ['lib','poems'] }), new HTMLPlugin({ template: './src/poem/article/article.html', filename: 'authors.html', chunks: ['lib','authors'] }), new HTMLPlugin({ template: './src/poem/article/article.html', filename: 'article.html', chunks: ['lib','article'] }), new HTMLPlugin({ template: './src/poem/article/article.html', filename: 'search.html', chunks: ['lib','search'] }) ], …… }
其中 lib
是拆包出来的公共库。我这里没有碰到 js 加载顺序的问题,如果有顺序问题,可以配置 html-webpack-plugin
插件的 chunksSortMode: 'manual'
解决问题。
四、 公共库打包问题
关于公共库打包折腾了很久。总体来说是配置不了解的问题。一开始配置大致如下:
new webpack.optimize.SplitChunksPlugin({ name:'vendor' }),
打包后发现,lib.js
文件确实存在了,文件也引入了,但是,其他的 js 文件体积并没有减小。(这里存在这个文件是因为有 lib 入口,而不是真的剥离公共库。)为什么?然后又是一通百度,总算找到了解决方法。SplitChunksPlugin
的配置应该这么写:
optimization: { splitChunks: { cacheGroups: { lib: { name: 'lib', filename: 'js/[name].[chunkhash:8].js', minChunks: 2, chunks: 'initial' } } } }
这个 optimization
应该在 config
下面,和 entry
平级。
好了,总算解决了。
五、css 拆分的问题
嗯,实际上,这个问题还没有解决。通过 mini-css-extract-plugin
确实可以将 css 剥离出来,但是,页面没有内容,控制台也没有报错。😭
所以,css 剥离只能暂时放弃了。
六、 环境配置问题
平时为了开发方便,引入的库都是未压缩的。环境设置为 development
,但上线时需要改为 production
。为了切换方便,以及解决跨平台问题。需要使用 cross-env
插件。package.json
脚本如下:
"build": "cross-env NODE_ENV=development webpack --config webpack.config.js && cp ./src/index.php ./dist/", "b_pro": "cross-env NODE_ENV=production webpack --config webpack.config.js && cp ./src/index.php ./dist/",
webpack.config.js
文件包含下面两句:
const isDev = process.env.NODE_ENV === 'development'; const config = { mode: isDev ? 'development' : 'production', …… }
七、 清理目标文件夹
手动清理目标文件夹很不方便,所以引入 clean-webpack-plugin
插件进行清理。
const clean = require('clean-webpack-plugin'); …… new clean(['dist']), ……
或者,在脚本里加入 linux 命令清理。(未尝试)
八、 vue 中 $emit 无法触发问题
事件名要小写。
九、 json 中 html 标签问题
因为需要将搜索的关键字在结果中高亮,所以在 php 中对结果字符串进行替换:
$result_array[$key]['d_poetry'] = str_replace($name,"<span style = \"color: red;\">".$name."</span>",$result_array[$key]['d_poetry']);
但是并没有达到预期中的结果。无论检查多少遍,尝试多少遍都不行。于是,另写一个测试文件。
<?php $text = "一"; $obj = new StdClass(); $obj -> text = "这是一行文字"; $str = "<span style=\" color:red\" >".$text."</span>"; $obj -> text = str_replace($text,$str,$obj -> text); echo $obj -> text; echo "<br>" echo json_encode($obj);
结果是什么呢?
qq 浏览器如下:
额,算了,过程比较曲折,直接说结果吧。
将 json_encode($obj)
改成 json_encode($obj,JSON_HEX_TAG)
。
参考:# json返回数据中带有html标签的输出
十、 url 中文转码问题
在发送请求的时候,ie 浏览器使用的不是 utf-8 编码,而是系统本地编码,比如 gbk。这样一来,中文的传输就成了问题。因为后台是 utf-8 编码。所以,我们需要对中文进行转码。
编码:
js: url = encodeURI(encodeURI(url));
解码:
php: url = urldecode(url);
部分 php 函数:
- is_array()
- count()
- file_get_contents()
- mysqli_connect()
- mysqli_query()
- mysqli_select()
- mysqli_num_rows()
- mysqli_fetch_all()
- mysqli_free_result()
- mysqli_close()
- isset()
- is_numeric()
- substr()
- urldecode()
- unset()
- array_unique()
- array_rand()
- str_replace()
- ceil()
成品
链接:诗词