Setup Development Environment

Install Bedrock with NPM

In a directory somewhere else in your local development environment, use npm to install Bedrock. On my local machine, I've created a directory named theme_bedrock_documentation. Within it, run:

npm i @concretecms/bedrock

(If you're new to npm, try checking out a basic tutorial on installation and usage. Here's An Absolute Beginner's Guide to NPM)

This will create package.json and package-lock.json file detailing the required assets for your project (which will consist of Bedrock and its dependencies). Those dependencies will be added into the node_modules/ directory within theme_bedrock_documentation.

Install Laravel Mix

Since Bedrock uses SCSS significantly, it makes sense to work with a preprocessor like Webpack. You're free to work with an asset processor like Webpack directly, or you can use something that makes interacting with it a little easier. For this purpose, we like Laravel Mix

Laravel Mix, a package developed by Laracasts creator Jeffrey Way, provides a fluent API for defining webpack build steps for your Laravel application using several common CSS and JavaScript pre-processors.

Laravel Mix allows developers to work with their assets and compile them down to shipping CSS and JS files using an easier-to-understand syntax than base Webpack. From within the same directory, install Laravel mix using npm:

npm i laravel-mix

Define Commands within package.json

Next, you'll need to add commands to your package.json. These will be available to be run with npm run, which is who you'll command your environment to build your CSS and JS files. Add the following commands to package.json:

"scripts": {
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "production": "mix --production"
}

The resulting package.json file should look something like this:

{
  "dependencies": {
    "@concretecms/bedrock": "^1.1.3",
    "laravel-mix": "^6.0.41"
  },
    "scripts": {
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "production": "mix --production"
    }
}

Important: make sure your JSON is formatted correctly within commas in the right place and no trailing commas. If your syntax is broken you will not be able to run commands until you fix it.

Test Your Environment

Now, let's try running the command you'll use to bundle your assets for production use (which minifies them, etc...) From within the directory, run

npm run production

(Note: this corresponds to the production command within the scripts section of your package.json file). You should get an error:

[webpack-cli] Error: Cannot find module '/path/to/project/theme_bedrock_documentation/webpack.mix'

This is expected; Laravel Mix requires a file named webpack.mix.js be present in the same directory. This file holds the JS commands detailing which files must be bundled, and where they ought to be output.

Let's create a simple stub file at webpack.mix.js in the same theme_bedrock_documentation directory:

Create webpack.mix.js

Let's create a basic webpack.mix.js file in the root of our build directory, theme_bedrock_documentation:

let mix = require('laravel-mix');

mix.webpackConfig({
    externals: {
        jquery: 'jQuery',
        bootstrap: true,
        vue: 'Vue',
        moment: 'moment'
    }
});

mix.setPublicPath('/path/to/my/concrete-cms/application/themes/flintstone');

mix
    .sass('assets/scss/main.scss', 'css/main.css')
    .js('assets/js/main.js', 'js/main.js');

Let's break this down line by line. First, we create a mix variable from the laravel-mix package that's already been downloaded by npm.

Next, we pass some values into the underlying webpackConfig object. Here, we're basically telling webpack that any time our Bedrock JS refers to jQuery, Bootstrap, Vue or Moment, that we're loading those libraries in externally – so we don't need to bundle them into the JS files that Laravel Mix will build. Concrete will handle including these files using the asset system.

Next, we set a global public package for this series of Laravel Mix operations. Any CSS or JS files we build will be going into our Flintstone theme directory, so let's set the public path to save additional keystrokes down below.

Finally, we run a assets/scss/main.scss file through a SASS preprocessor, and output it into the css/main.css file found within the Flintstone theme directory, and we run assets/js/main.js through a JS minifier and ES6 processor, and output it to js/main.js found in our the Flintstone theme directory.

This is enough for Laravel Mix. However, if we ran npm run production again, we'd get complaints about missing files. That's because we haven't created the main.scss and main.js files in our assets/ directory that Laravel Mix wants to work with. Let's create them next.

Create Empty JS and SCSS Files

Create two empty files found at

theme_bedrock_documentation/assets/js/main.js
theme_bedrock_documentation/assets/scss/main.scss

Now that these files exist (even though they're empty), we can run Laravel Mix.

Run Laravel Mix

From within theme_bedrock_documentation, run npm run production. This should result in something very similar to this:

#

(Note: you may get notes about needed to install additional modules. Continue to run npm run production. If you receive these notices multiple times, try running npm i again before running npm run production again.)

Verify Files

Now, let's verify that the files are created where they're supposed to be. Within your application/themes/flintstone directory, you should see an empty JS and CSS file in the proper spots:

#

Now the fun starts!