laravel elixir - combining scripts multiple times - laravel

I want to combine all my scripts into one minified javascript file, but I'm having trouble combining them.
mix.browserify([
// ViewModels
'viewmodels.js'
], 'resources/assets/compiled/js/viewmodels.js')
mix.coffee([
// WebSocket Client
'client.coffee'
], 'resources/assets/compiled/js/').scripts([
// Vendor
'vendor/jquery.js',
'vendor/bootstrap.js',
'vendor/vue.js',
'vendor/sisyphus.js',
'vendor/leaflet.js',
'vendor/moment.min.js'
], 'resources/assets/compiled/js/vendor.js').scripts([
// Site & Helpers
'libs/laravel.js',
'libs/helpers.js'
], 'resources/assets/compiled/js/site.js').scripts([
// Combine Scripts
'resources/assets/compiled/js/vendor.js',
'resources/assets/compiled/js/client.js',
'resources/assets/compiled/js/site.js',
'resources/assets/compiled/js/viewmodels.js'
], 'public/js/all.js', './')
The files are created in resources/assets/compiled/js, so I've got:
client.js
site.js
vendor.js
viewmodels.js
The last task that's run is the scripts task combining the four files.
The elixir log states (I simplified the ouput):
Browserify (ViewModels)
CoffeeScript Compiled
Merging Vendor
Merging Site & Helpers
Merging Combine Scripts
... and these are the error messages I get:
File not found: ./resources/assets/compiled/js/vendor.js
File not found: ./resources/assets/compiled/js/site.js
I did the exact same thing with sass and styles and it worked perfectly.
mix.sass([
// Vendor
'resources/assets/sass/fontawesome/font-awesome.scss',
// Site
'resources/assets/sass/site/site.scss'
], 'resources/assets/compiled/css/').styles([
// Vendor
'resources/assets/css/bootstrap.min.css',
'resources/assets/css/hover-min.css',
'resources/assets/css/leaflet.css',
'resources/assets/compiled/css/font-awesome.css',
// Site
'resources/assets/compiled/css/site.css'
], 'public/css/all.css', './').version(
'public/css/all.css'
)

Why don't you merging the scripts all at once instead of doing it 3 times ?
Try like this
mix.coffee([
// WebSocket Client
'client.coffee'
], 'resources/assets/compiled/js/')
.scripts([
// Vendor
'resources/assets/js/vendor/jquery.js',
'resources/assets/js/vendor/bootstrap.js',
'resources/assets/js/vendor/vue.js',
'resources/assets/js/vendor/sisyphus.js',
'resources/assets/js/vendor/leaflet.js',
'resources/assets/js/vendor/moment.min.js',
// Site & Helpers
'resources/assets/js/libs/laravel.js',
'resources/assets/js/libs/helpers.js',
'resources/assets/compiled/js/client.js',
'resources/assets/compiled/js/viewmodels.js'
], 'public/js/all.js', './');

Related

Minify a CSS and HTML file to the same location using Laravel Mix

I have two files, one CSS and one HTML in these locations:
resources/js/example/file.css
resources/js/example/file.html
What I would like to do using Laravel Mix (webpack) is
Minify the CSS file into file.min.css into the same directory
Minify the HTML file into file.min.html into the same directory
I have tried:
mix.postCss('resources/js/example/file.css', 'resources/js/example/file.min.css', [
require('cssnano')
]);
But this creates the CSS file in public/js/example/file.min.css.
I'm not sure why you don't want compiled files to be in the public directory. Regardless, you can use mix.setPublicPath() to change the output directory. This will tells Mix what you want the basic directory where all of your assets should be compiled to.
webpack.mix.js
const mix = require('laravel-mix');
mix.setPublicPath('');
mix.postCss('resources/js/example/file.css', 'resources/js/example/file.min.css', []);
If you want to Mix and minify HTML files you can install this plugin.
npm install minify-html-webpack-plugin --save-dev
Then add to your webpack...
const MinifyHtmlWebpackPlugin = require('minify-html-webpack-plugin');
const mix = require('laravel-mix');
mix.setPublicPath('');
mix.postCss('resources/js/example/file.css', 'resources/js/example/file.min.css', []);
mix.webpackConfig({
plugins: [
new MinifyHtmlWebpackPlugin({
afterBuild: true,
src: './resources/js/example',
dest: './resources/js/example',
ignoreFileNameRegex: /\.(gitignore|php)$/,
ignoreFileContentsRegex: /(<\?xml version)|(mail::message)/,
rules: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true,
minifyJS: true,
}
})
]
});
And make a dev or production build. Keep in mind you will have to play around with the src and dest to get the output exactly the way you want it.

How to combine `css-modules` with normal `sass`, preferably in `webpack`

TLDR: How to combine css-modules with normal sass, preferably in webpack.
The Setup:
I am working on the styling build process for an e-commerce website. The site's styles are currently done in sass along with the js through a gulp browserify build process.
I have recently added a single page app that is built using react with webpack and babel. Inside of that application I am taking advantage of css-modules provided by webpack to scope the class names to each react component.
The problem:
I would like to incorporate the styles from the webpack css-modules build in with the main styling bundle for the site. To do this, I was considering building a webpack configuration to build the styles for the whole site. The problem I have is how to get the styles which are currently built by the single page webpack configuration and inject just the style chunk into a global webpack configuration that handles styles for the whole site. I should mention that I would like to keep the two configurations as separate as possible
The Questions:
Is there a proper way of having decoupled webpack builds where one is still able to use chunks from the other?
If so, how do I do it so that the css-module setup stays in the single page configuration, and the extract-text-webpack part along with a boring sass build goes into a global configuarion?
If not, how should I go about having one section of sass go through the css-modules workflow, and still combine it with the bundle from the rest of the site.
Thanks in advance.
EDIT
based on #Alexandr Subbotin's answer, I have updated my webpack to look something like the code below. I did have to change names and paths because of the code belongs to my employer, so there may be slight errors.
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const JSDIR = './build/js/';
const STYLES = './build/css/bundle.css';
module.exports = {
entry : {
'styles' : './src/styles.scss',
'app' : './src/index.js',
// a javascript file that includes the root of the single page app.
'single-page' : './src/single-page/styles-entry.js',
},
output : {
path : JSDIR,
filename : '[name].js', // normally compiles my
publicPath: 'http://localhost:8080/',
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader : 'babel-loader',
query : {
presets: [
'react','es2015','stage-0',
]
},
},
{
test : /\.scss$/,
loader: ExtractTextPlugin.extract('style?sourceMap', 'css?-url&sourceMap!sass?sourceMap'),
exclude : /\/single-page\//,
},
{
test : /\.scss$/,
loader: ExtractTextPlugin.extract(
'style?sourceMap',
'css?-url&modules&importLoaders=1&localIdentName=SinglePage__[name]__[local]!sass?sourceMap'
),
include : /\/single-page\//,
}
]
},
plugins : [
new ExtractTextPlugin(STYLES, {
allChunks : true,
}),
],
resolve : {
alias: {
"eventEmitter/EventEmitter": "wolfy87-eventemitter",
},
extensions: ['', '.js','.jsx'],
},
}
If I understood your question you want to apply css-modules only to one part of your application and leave simple sass building process in other parts.
To do this you can use exclude and include options in loaders. I.e. if you have your single page application inside single-page directory your webpack config can be:
module: {
entry: {
// it is your global sass styles
application_css: './css/application.scss',
// it is main file of your SPA bundle. Somewhere inside you will use require('./styles.scss') that should be processed by css-modules
spa_index: './single-page/index.js'
},
loaders: [
...,
{
// This loader will build all your sass that are not in `single-page` directory
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', 'css!sass'),
exclude: /\/single-page\//
},
{
// This loader will handle all your css module in `single-page` directory
test: /\.scss$/,
loader: 'style!css?modules!sass',
include: /\/single-page\//
},
],
...
}
So, in this case all css from single-page/ will use css modules, and the rest won't.
EDIT:
If you take a look in API section of ExtractTextPlugin documentation you find
The ExtractTextPlugin generates an output file per entry, so you must use [name], [id] or [contenthash] when using multiple entries.
In your example you have have two chunks with css (styles and single-page), but only one output ./build/css/bundle.css. If you change your output to ./build/css/[name].css your will have two css files: styles.css with your global css and single-page.css with SPA styles.

separate gulp Concat locations

I'm working on a project that has two separate js folders for user (public/js) and admin usage (public/admin_stuff/js).
I'm going to have two all.js files , one for user section js files and another for admin section js files . how can i achieve that in a neat way?
If you are using elixir, then:
// For admin
mix.scripts([
'admin_js_source_folder/**/*.js',
], 'public/admin_stuff/js/all.js');
// Another
mix.scripts([
'other_folder_js_files/**/*.js',
], 'public/other/js/all.js');
Other cases:
gulp.task('admin', function() {
return gulp.src('admin_stuff/js/**/*.js')
.pipe(concat('all.js'))
.pipe(gulp.dest('public/admin'));
})
gulp.task('other', function() {
return gulp.src('other/js/**/*.js')
.pipe(concat('all.js'))
.pipe(gulp.dest('public/other'));
})
gulp.task('default', ['admin', 'other']);
If your are using laravel 5, i recommend using elixir:
https://laravel.com/docs/5.0/elixir

Laravel Elixir version rev-manifest incomplete on gulp default task

I have my gulpfile (using Laravel Elixir) set up to create 4 files.
app.css
app.js
vendor.css
vendor.js
When I run either gulp, or gulp default app.js does not get created. Yet if I run gulp watch, it is created perfectly.
Here is the elixir method:
elixir(function(mix) {
// Register html watcher
mix.templates()
// Compile app css
.sass('app.scss', null, {
includePaths: require('node-bourbon')
.with(require('node-neat').includePaths)
})
// Concatenate vendor css
.styles([
...
], 'public/css/vendor.css', 'public/css/vendor')
// Minify & concatenate vendor js
.scripts([
...
], 'public/js/vendor.js', 'public/js/vendor')
// Minify and concatenate app js
.scriptsIn('resources/assets/js', 'public/js/app.js')
// Version the compiled resources
.version([
'css/app.css',
'js/app.js',
'css/vendor.css',
'js/vendor.js'
]);
});

Karma/Jasmine - Test Files not loading in Base, Module Not Defined

I'm having a hell of a time with Karma/Jasmine. I'm just trying to run the example specs from Jasmine's site.
When I run jasmine on command line, the tests run fine. However, if I try to run them using Karma test runner, I have a multitude of problems.
Here's My File Structure
Here's my karma.conf.js file:
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'requirejs'],
// list of files / patterns to load in the browser
files: [
'node_modules/requirejs/require.js',
'**/test-main.js', {
pattern: 'spec/jasmine_examples/*.js',
included: false
}
],
// list of files to exclude
exclude: ['**/*conf.js'],
...port,browser etc.
Here's my test.main.js file
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;
var pathToModule = function(path) {
return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
allTestFiles.push(pathToModule(file));
}
});
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: '/base',
// dynamically load all test files
deps: allTestFiles,
// we have to kickoff jasmine, as it is asynchronous
callback: window.__karma__.start
});
When I run karma start, I get a 404 that PlayerTest.js and SongTest.js are not under base/. However they are loaded and located in base/spec/jasmine_examples. In addition, PlayerTest.js throws an error "module not defined".
Honestly, what am I doing wrong?
I think you need to refer to the karma-requirejs and the karma-jasmine plugins in the karma.conf.js file -
config.set({
plugins: [
'karma-jasmine',
'karma-requirejs'
],
From karma doc, it states:
Please note just about all frameworks in Karma require an additional plugin/framework library to be installed (via NPM).
Additional information can be found in plugins.
You will not need to have require.js in the files section.

Resources