Vue.js - Compile .vue file with gulp - javascript

I have a Vue component. This component is very basic and looks like this:
my-component.vue
<template>
<div class="foo">
</div>
</template>
<script>
export default {
data() {
return {};
},
props: {
message: {
type: String,
default: ''
}
},
methods: {
display: function() {
alert(this.message);
}
},
};
</script>
I want to import it into an HTML file using something like this:
<script type="text/javascript" src="/components/my-component.min.js"></script>
Then, I would like to be able to just use the component in my HTML file like this:
<my-component message="hello"></my-component>
Is this possible? If so, how? Everything that I see uses web pack and a bunch of other stuff. I have a working component. I just can't figure out how to make it easily deployable.
I created a gulpfile to help with this. This looks like this:
gulpfile.js
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var webpack = require('webpack-stream');
gulp.task('default', ['build']);
gulp.task('build', [], function() {
return gulp.src('./src/my-component')
.pipe(webpack(require('./webpack.config.js')))
.pipe(concat('my-component.min.js'))
.pipe(gulp.dest('./deploy'))
;
});
When I run the build gulp task, I receive a message that says:
webpack-stream - No files given; aborting compilation
The confusing part is, I have some unit tests that successfully work. I'm running those tests via this command:
nyc mocha-webpack --webpack-config ./webpack.config.js test --recursive --require test/.setup
What am I doing wrong? How do I package up my component so that I can import it into other apps?

If you don't want to use any bundle - a full webpack bundle (please reconsider this decision if you are working on a big project) nor browserify (see vueify)... then you may use this package to compile single file component into single js file, with gulp:
https://www.npmjs.com/package/gulp-vueify2
I must mention that I am the author of this module.

Related

Bundling with webpack from script

I am using webpack to bundle my Javascript files in my project:
webpack --config myconfig.webpack.config.
From commandline it is ok.
Building
However I would like to create a build task, I am using jake, so in order to create the bundle I need to invoke webpack from Javascript.
I could not find the API online, I basically need something like this:
// Jakefile.js
var webpack = require("webpack");
desc('This is the default build task which also bundles stuff.');
task('default', function (params) {
webpack.bundle("path-to-config"); // Something like this?
});
How do I achieve this?
Attempt 1
I have tried the following:
// Jakefile.js
var webpack = require("webpack");
var config = require("./webpack.config.js");
desc('This is the default build task which also bundles stuff.');
task('default', function (params) {
webpack(config);
});
webpack.config.js is my config for webpack. When I use from commandline and reference that file the bundle is correctly created. But when using the above code it does not work. When I execute it, no errors, but the bundle is not emitted.
In your Attempt 1, you seem to be consuming the webpack's Node.js API by passing the config to webpack method. If you take this approach, webpack method will return a compiler object and you need to handle it correctly.
For e.g.,
import webpack from 'webpack';
var config = {}; // Your webpack config
var wpInstanceCompiler = webpack(config);
wpInstanceCompiler.run(function(err, stats) {
if (stats.hasErrors()) {
console.log(stats.toJson("verbose");
}
});
This is how you execute a webpack config via the Node.js API. Unless you run the compiler instance, the output will not get generated.
This worked for me as well:
var webpack = require("webpack");
var lib = require(path.join(__dirname, "webpack.config.js"));
desc('Builds the projects and generates the library.');
task('default', function() {
webpack(lib, function() {
console.log("Bundle successfully created!");
});
});

Generate a local HTML file with PUG (npm / gulp)

How to create a HTML file with the same name as my pug file each time I save using gulp?
All the docs on https://pugjs.org/ explain how to return pug in console...
You need task runner or module bundler for that. So choose one -grunt/gulp/webpack. Consider webpack as newest one and width best functionality.
Here an example width gulp as moust easy to understand from my point of view.
First install npm packages for compiling pug and watch for changes - npm install --save gulp-pug gulp-watch.
Then create and config your gulpfile.js.
First import an npm modules
var pug = require('gulp-pug');
var watch = require('gulp-watch');
Then create compiling task
gulp.task('pug',function() {
return gulp.src('PATH_TO_TEMPLATES/*.jade')
.pipe(pug({
doctype: 'html',
pretty: false
}))
.pipe(gulp.dest('./src/main/webapp/'));
});
And then create watcher
gulp.task('watch', function () {
return watch('PATH_TO_TEMPLATES/*.jade', { ignoreInitial: false })
.pipe(gulp.dest('pug'));
});
And run gulp-watch from you console.
Here an example width gulp 4.0
install npm packages for compiling pug/jade by following command
npm install --save gulp-pug .
create script with name gulpfile.js
//gulpfile.js
var gulp = require("gulp"), pug = require('gulp-pug');
function pugToHtml(){
return gulp.src('src')
.pipe(pug({
pretty: true
}))
.pipe(gulp.dest('dest'));
}
exports.pugToHtml = pugToHtml;
We can run the above code using the following command in your file directory:
gulp pugToHtml
You can now do the same without requiring gulp-watch as well.
Require module:
var pug = require('gulp-pug');
Task example:
//create task
gulp.task('pug', function buildHTML(){
gulp.src('src/pre/*.pug')
.pipe(pug())
.pipe(gulp.dest('src/post'));
});
Watch:
//pug serve
gulp.task('watch', ['pug'], function() {
gulp.watch(['src/pug-pre/*.pug'], ['pug']);
});
You can then run gulp watch. You can also set watch to the default task so you only have to write gulp in Terminal, if you are not automating anything else:
// default task
gulp.task('default', ['watch']);

Getting started with unit testing JavaScript without a framework

I am building a JavaScript application (no framework yet, but I may move it to Backbone). I have created various classes, here's an example, chart.js:
var moment = require('moment');
var chart = {
...
getAllMonths: function(firstMonth, lastMonth) {
var startDate = moment(firstMonth);
var endDate = moment(lastMonth);
var monthRange = [];
while (startDate.isBefore(endDate)) {
monthRange.push(startDate.format("YYYY-MM-01"));
startDate.add(1, 'month');
}
return monthRange;
},
setMonths: function() {
// get data via ajax
this.globalOptions.months = this.getAllMonths(data['firstMonth'], data['lastMonth']);
}
};
module.exports = chart;
My file structure is as follows:
index.js
src/
chart.js
form.js
I import the two classes into index.js and use browserify to bundle these scripts up in order to use them in my web app.
Now I want to add tests for chart.js and form.js. I have added a new directory called test/ and empty test files:
index.js
src/
chart.js
form.js
test/
test_chart.js
test_form.js
My question now is what test_chart.js should look like in order to test the getAllMonths function, and what test runner I should use.
I've started experimenting with the following in test_chart.js:
console.log('hello world');
var chart = require('../src/chart');
var months = chart.getAllMonths('2014-02-01', '2015-03-01');
// assert if months.length != 14
But if I run this with node test/test_chart.js, I get errors about failed module imports for moment etc (shouldn't these be imported automatically with the original chart.js module?).
Secondly, what test runner could I use for this kind of simple testing? I'd like something that will automatically run everything in the test directory, and offers asserts etc.
I ended up using Mocha. It's really pretty easy:
npm install --save-dev mocha
mocha
Boom!
It automatically looks for files in the test/ folder.
Still having the problem with imports though.

Getting started with browserify: import local files?

I have been prototyping a JavaScript application and now I want to move to a more robust setup using browserify and managing dependencies with require.
Currently I have the following files in my application:
chart.js
form.js
highcharts-options.js
vendor/
highcharts.js
jquery.js
highcharts-options.js is basically a list of constants, while chart.js looks like this...
var myChart = {
setup: function(data) { ... this.render(data); },
render: function(data) { ... }
},
and form.js looks like this:
var myForm = {
setup: function() { button.onclick(_this.getData(); },
getData: function() { // on ajax complete, callChart },
callChart: function() { myChart.setup(data); }
};
myForm.setup();
And then I have an index.html page that imports everything as follows:
<script src="/js/vendor/highcharts.js"></script>
<script src="/js/vendor/jquery.js"></script>
<script src="/js/highcharts-options.js"></script>
<script src="/js/chart.js"></script>
<script src="/js/form.js"></script>
So now I want to move this to a more modern setup with browserify.
I have deleted the vendor directory and instead created an index.js file and a package.json file, so now my directory structure looks like this:
index.js
package.json
chart.js
form.js
highcharts-options.js
node_modules/
I have run npm i --save highcharts-browserify and npm i --save jquery and that has saved these modules to package.json and installed them in node_modules. I've also added a build task in package.json: browserify index.js -o bundle.js. And in my front-end template I know just have:
<script src="/js/bundle.js"></script>
So far so good.
My question is what to put into my index.js file, because I'm not sure how to import the files that I already have. So far I've got this:
var $ = require('jquery');
var HighCharts = require('highcharts-browserify');
var options = require('highcharts-options');
var myChart = require('chart');
var myForm = require('form');
myForm.setup();
But when I try to build this, I get:
Error: Cannot find module 'chart' from '/mypath/static/js/app'
It looks like require doesn't know how to find this file, or how to import it, which is not surprising given that this is all total guesswork on my part.
How should I adapt these files to work in a more modular way? Am I on the right lines, or is this completely the wrong approach? I'm not even sure what I should be Googling for.
(NB: Eventually I want to refactor chart.js and form.js to use Backbone, but I need to work one step at a time.)
You are very close!
First, the way to reference a module in the same directory is to say:
var myChart = require('./chart');
Without the leading path component, require will look in your npm package directory.
Second, you need to export the variables in the modules so that they can be used elsewhere. So your form module needs to look something like this:
var myForm = {
setup: function() { button.onclick(_this.getData(); },
getData: function() { // on ajax complete, callChart },
callChart: function() { myChart.setup(data); }
};
myForm.setup();
module.exports = myForm;
I just finished struggling with this error for a while, I'll post my solution in case anyone else runs into the same issue I did. It seems that Browserify sometimes can't find local modules depending on where the require goes. This code didn't work:
window.Namespace = {
foo: new require('./foo.js')()
};
but this worked fine:
var Foo = require('./foo.js');
window.Namespace = {
foo: new Foo()
};

Gulp with browserify, tsify, and reactify?

I'm using gulp with browserify and tsify in a TypeScript project. The following is an extract from my gulpfile.js:
var browserified = function (filename, debug) {
var b = browserify({
entries: filename,
debug: debug || false
});
b.plugin('tsify', {
noImplicitAny: true,
target: 'ES5'
});
b.transform('debowerify');
return b.bundle();
};
gulp.task('rebuild', ['lint', 'less'], function() {
var b = browserified ('./src/ts/main.ts', true);
return buildSourceMaps (b);
});
This works so far. I want to extend this so I can require React JSX files. First I tried (from one of my TypeScript files):
import Test = require ('../jsx/Test.jsx');
This doesn't work, though, because tsify would complain as it looks for a TypeScript file ../jsx/Test.jsx.ts. So I use the following hack:
declare var require: any;
var Test = require ('../jsx/Test.jsx');
If Test.jsx is plain vanilla JavaScript, this works. If Test.jsx contains TypeScript, it would fail, which is what I expect. So far, so clear.
Now I want to add reactify to my gulp tasks so I can use JSX in these files. Here I am stuck! I tried adding the following to the function browserified in my gulpfile.js:
b.plugin ('reactify', {
extension: 'jsx'
});
I still get the following error when I call gulp rebuild when Test.jsx contains actual JSX:
Unexpected token <
Obviously, gulp chokes on the first JSX-specific term. I think gulp is trying to pass the JSX through the TypeScript compiler. Which isn't a surprise, since I can't think of a way how to tell tsify to ignore my .jsx files. I'm new to gulp, so I am a bit at a loss. Any ideas how to set up gulp to allow for TypeScript with all .ts files and JSX with all .jsx files?
This is the gulp task I use for development. It uses watchify along with browserify and reactify to build your code, provide source mapping, and rebundle any changes you make on the fly. The path.ENTRY_POINT variable is the main component for your react app (often app.js or main.js).
gulp.task('watch', function() {
gulp.watch(path.HTML, ['copy']);
var watcher = watchify(browserify({
entries: [path.ENTRY_POINT],
transform: [reactify],
debug: true,
cache: {}, packageCache: {}, fullPaths: true
}));
return watcher.on('update', function () {
watcher.bundle()
.pipe(source(path.OUT))
.pipe(gulp.dest(path.DEST_SRC))
console.log('Updated');
})
.bundle()
.pipe(source(path.OUT))
.pipe(gulp.dest(path.DEST_SRC));
});
I used this tutorial to set up my gulpfile.js and it provides a good explanation for every gulp task:
http://tylermcginnis.com/reactjs-tutorial-pt-2-building-react-applications-with-gulp-and-browserify/

Categories

Resources